Limbajul SQL. Structura comenzii SQL

SQL este un limbaj de interogare structurat. SQL nu există fără baze de date - nu poți scrie programe pe el, iar în acest sens nu este un limbaj de programare precum PHP, dar atunci când ai de-a face cu un anumit SGBD, nu te poți descurca fără cunoștințe de SQL. Puteți scrie interogări simple pe el sau puteți efectua tranzacții mari constând din mai multe interogări complexe. O interogare SQL este un fel de comandă către o bază de date. O astfel de comandă poate solicita returnarea informațiilor care îndeplinesc anumite criterii sau poate solicita ștergerea oricăror înregistrări etc. O comandă SQL este un șir simplu, ca acesta:

SELECTAȚI * DIN departamentul Staff WHERE

Interogările SQL sunt de obicei aproape de o expresie simplă în limba engleză. Comanda de mai sus poate fi tradusă în rusă după cum urmează

SELECTAȚI TOTUL din Staff WHERE clwjiertme"

Echipa destul de înțeleasă, păcat că este înregistrat doar în engleză. Ca rezultat al executării unei astfel de interogări, DBMS va returna toate înregistrările din tabelul Staff în care câmpul depart* Mit_id este egal cu trei. În exemplul nostru, această interogare selectează de fapt numai programatori din întreaga bază de angajați.

Dacă nu ați mai lucrat cu un SGBD, atunci este posibil să aveți o întrebare rezonabilă: unde și cum poate fi executată această interogare? Există trei moduri de a executa interogări SQL.

1. Mediu interactiv pentru interacțiunea cu SGBD. Pentru majoritatea serverelor DBMS, există programe client (încorporate sau furnizate de terți) în mediul de lucru al cărora puteți scrie interogări SQL, le puteți executa și obține rezultatul. De obicei, astfel de instrumente sunt folosite de administratorii bazelor de date și nu au legătură directă cu programarea PHP. Un exemplu de program client MySQL este programul MySQL Administrator (http: /www.mysgl.coin/product-s/administratoT/) sau foarte popularul sistem PHP phpMyAdmin (http: / /www.phpmyadi'ln.r»et /itummjiage/index.php). Pentru a începe, va fi suficient un kit de distribuție deja instalat, care are o interfață de consolă. Pe Linux, trebuie să tastați comanda mysql din linia de comandă pentru a deschide o fereastră cu o invitație de a introduce interogări SQL, iar pe Windows, pentru a lansa aceeași interfață, trebuie să rulați fișierul mysql. exe din directorul bin.

2. Interogări SQL statice. De obicei, astfel de interogări sunt scrise în cadrul procedurilor stocate în bazele de date în sine sau conectate în aplicații în sine. O interogare SQL statică este predefinită și se modifică numai dacă programul sau codul procedurii stocate este rescris manual. Din PHP, o astfel de interogare SQL este executată folosind funcții speciale, care vor fi discutate în continuare.

3. Interogări SQL dinamice. Acest tip include astfel de interogări, iar când scriu aplicația nu poate fi pe deplin definită. i „de exemplu, când scrieți un program pentru a obține o listă a unui angajat” la diferite departamente ale întreprinderii, programatorul nu știe, ci „> despre compania va avea departamente și care angajați vor fi incluși în ele i „. Desigur, aceste date pot fi scrise în program în mod rigid, dar odată cu prima modificare a structurii companiei, programul poate fi aruncat sau va trebui rescris. Interogările dinamice vă permit să creați programe care sunt flexibile la modificările datelor .În PHP, astfel de interogări sunt efectuate de aproape aceleași funcții ca și cele statice, doar că în ele '^in'> Nu este posibil să treci unii parametri.

Ca un rezumat al celor trei puncte de mai sus, putem spune că interogările SQL sunt executate din programe administrative speciale sau în diverse moduri din scripturi PHP.

Deoarece SGBD rezolvă multe probleme, SQL trebuie să fie, de asemenea, un limbaj multifuncțional. Există mai multe tipuri de operații care pot fi< \ ществлять с помощью SQL.

1. Determinarea structurii bazei de date. Acest tip include interogări care creează și modifică tabele și indecși. De obicei, acestea sunt comenzi CRE; "E TA' LE, ALI'R TA' LE, ' ” '. TE INDEX etc.

2. Manipularea datelor. Acest tip include cereri de inserare (mutare*și> leni), ștergere sau modificare a datelor din tabele. Acestea sunt cele trei comenzi principale: INSERT. ȘTERGEȚI ȘI ACTUALIZAȚI.

3. Selectarea datelor Aceasta include o singură instrucțiune SELECT. Nu aduce modificări datelor în sine, dar vă permite să le obțineți din baza de date. Chiar dacă o singură comandă este folosită pentru a prelua date, este foarte puternică și este folosită foarte des în aplicații.

4. Managementul serverului DBMS. Acest tip include în principal solicitări de gestionare a utilizatorilor și a drepturilor lor de acces (de exemplu, comanda GRANT).

Cunoașterea bună a SQL facilitează foarte mult munca unui programator atunci când lucrează cu o bază de date. Aplicațiile pot fi mici, dar au o funcționalitate excelentă doar datorită faptului că SQL va prelua o mulțime de sarcini.

Ca în orice altă zonă a IT, există standarde în SQL - acesta este ANSI SQL. Abrevierea ANSI înseamnă Institutul Național American de Standarde (American National Standards Institute). Cu toate acestea, nu în ultimul rând din cauza diferenței de funcționalitate a DBMS în sine, implementarea SQL pentru diferite

Cu toate acestea, DBMS diferă unul de celălalt. În prezent, aproape fiecare DBMS are propriul său dialect, care de obicei nu diferă mult de standardul general, dar are propriile sale caracteristici. De exemplu, PL/SQL este compatibil cu Oracle și PostgreSQL, iar T-SQL este folosit pentru a lucra cu MS SQL Server.

Pentru munca ulterioară cu bazele de date, vă recomandăm să studiați imediat standardul cu care intenționați să lucrați în viitor. Pentru majoritatea dezvoltatorilor Web, funcționalitatea SGBD-ului MySQL (și poate fi folosit gratuit) este suficientă pentru cap în acest moment, așa că în această carte vor fi date, respectiv, toate exemplele MySQL în dialectul acestui SGBD. Documentația limbajului de interogare pentru MySQL poate fi găsită la www.mysql.com.

Limbaj de programare

SQL (Structured Query Language - Structured Query Language) este un limbaj de gestionare a bazelor de date pentru baze de date relaționale. SQL în sine nu este un limbaj de programare complet Turing, dar standardul său vă permite să creați extensii procedurale pentru acesta, care își extind funcționalitatea într-un limbaj de programare cu drepturi depline.

Limbajul a fost creat în anii 1970 sub numele „SEQUEL” pentru sistemul de management al bazelor de date (DBMS) System R. Ulterior a fost redenumit „SQL” pentru a evita conflictele de mărci înregistrate. În 1979, SQL a fost publicat pentru prima dată ca produs comercial, Oracle V2.

Primul standard de limbă oficială a fost adoptat de ANSI în 1986 și ISO în 1987. De atunci, au mai fost create câteva versiuni ale standardului, unele dintre ele repetându-le pe cele precedente cu variații minore, altele luând noi caracteristici semnificative.

În ciuda existenței standardelor, cele mai obișnuite implementări SQL diferă atât de mult încât codul poate fi rareori portat de la un SGBD la altul fără modificări majore. Acest lucru se datorează lungimii și complexității standardului, precum și lipsei de specificații în unele domenii importante de implementare.

SQL a fost creat ca o modalitate simplă, standardizată de a prelua și manipula datele conținute într-o bază de date relațională. Mai târziu, a devenit mai complex decât s-a prevăzut și s-a transformat într-un instrument pentru dezvoltator, nu pentru utilizatorul final. În prezent, SQL (în cea mai mare parte implementat de Oracle) rămâne cel mai popular dintre limbajele de baze de date, deși există o serie de alternative.

SQL este format din patru părți distincte:

  1. Data Definition Language (DDL) este folosit pentru a defini structurile de date stocate într-o bază de date. Instrucțiunile DDL vă permit să creați, să modificați și să ștergeți obiecte individuale din baza de date. Tipurile de obiecte valide depind de SGBD utilizat și includ de obicei baze de date, utilizatori, tabele și un număr de obiecte suport mai mici, cum ar fi roluri și indecși.
  2. Limbajul de manipulare a datelor (DML) este folosit pentru a prelua și modifica datele dintr-o bază de date. Instrucțiunile DML vă permit să preluați, să inserați, să modificați și să ștergeți date din tabele. Uneori, instrucțiunile de selectare pentru extragerea datelor nu sunt considerate parte a DML deoarece nu schimbă starea datelor. Toate instrucțiunile DML sunt declarative.
  3. Data Access Definition Language (DCL) este folosit pentru a controla accesul la datele dintr-o bază de date. Declarațiile DCL se aplică privilegiilor și vă permit să acordați și să revocați drepturi de a aplica anumite instrucțiuni DDL și DML anumitor obiecte de bază de date.
  4. Transaction Control Language (TCL) este folosit pentru a controla procesarea tranzacțiilor din baza de date. În mod obișnuit, declarațiile TCL includ commit to commit modificările făcute în timpul unei tranzacții, rollback pentru a le anula și salvare pentru a împărți tranzacția în mai multe părți mai mici.

Trebuie remarcat faptul că SQL implementează o paradigmă de programare declarativă: fiecare instrucțiune descrie doar acțiunea necesară, iar SGBD decide cum să o efectueze, adică. planifică operaţiile elementare necesare realizării acţiunii şi le execută. Cu toate acestea, pentru a utiliza eficient puterea SQL, dezvoltatorul trebuie să înțeleagă cum DBMS analizează fiecare instrucțiune și își creează planul de execuție.

Exemple:

Salut Lume!:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

Șirul „Hello, World!” este selectat din tabelul dual încorporat, folosit pentru interogări care nu necesită acces la tabele reale.

selectați „Hello World!” din dual ;

factorial:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

SQL nu acceptă bucle, recursiuni sau funcții definite de utilizator. Acest exemplu demonstrează o posibilă soluție folosind:

  • nivel de pseudo-coloană pentru a crea pseudo-tabele t1 și t2 care conțin numere de la 1 la 16,
  • funcția agregată sum , care vă permite să însumați elementele unei mulțimi fără a utiliza în mod explicit o buclă,
  • și funcțiile matematice ln și exp , care vă permit să înlocuiți produsul (necesar pentru a calcula factorialul) cu suma (furnizată de SQL).

Șirul „0! = 1” nu va fi inclus în setul de rânduri rezultat, deoarece încercarea de a evalua ln(0) are ca rezultat o excepție.

numerele Fibonacci:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

SQL nu acceptă bucle sau recursivitate, iar concatenarea câmpurilor din diferite rânduri dintr-un tabel sau o interogare nu este o funcție de agregare standard. Acest exemplu folosește:

  • Formula lui Binet și funcțiile matematice ROUND , POWER și SQRT pentru a calcula al n-lea număr Fibonacci;
  • nivel de pseudo-coloană pentru a crea un pseudo-tabel t1 care conține numere de la 1 la 16;
  • funcția încorporată SYS_CONNECT_BY_PATH pentru concatenarea ordonată a numerelor primite.

SELECTARE REPLACE (MAX (SYS_CONNECT_BY_PATH (fib || ", " , "/" )), "/" , "" ) || „...” fiblist FROM ( SELECT n , fib , ROW_NUMBER () OVER (ORDER BY n ) r FROM (selectați n , rotund ((putere ((1 + sqrt (5 ) )) * 0 . 5 , n ) - putere ((1 - sqrt (5 )) * 0 . 5 , n )) / sqrt (5 )) fib din (selectați nivelul n din conectarea duală după nivel<= 16 ) t1 ) t2 ) START WITH r = 1 CONNECT BY PRIOR r = r - 1 ;

Salut Lume!:

Exemplu pentru versiunile Microsoft SQL Server 2005 , Microsoft SQL Server 2008 R2 , Microsoft SQL Server 2012 , MySQL 5 , PostgreSQL 8.4 , PostgreSQL 9.1 , sqlite 3.7.3

selectați „Hello World!” ;

factorial:

Exemplu pentru Microsoft SQL Server 2005 , Microsoft SQL Server 2008 R2 , Microsoft SQL Server 2012

Se folosește definiția recursivă a factorialului, implementată printr-o interogare recursivă. Fiecare linie a interogării conține două câmpuri numerice, n și n!, iar fiecare linie ulterioară este calculată folosind datele din cea precedentă.

Puteți calcula factoriali întregi doar până la 20!. Când încerci să calculezi 21! apare o „Eroare de depășire aritmetică”, adică are loc debordare.

Pentru numerele reale se calculează factorialul 100! (Pentru a face acest lucru, în exemplu, trebuie să înlocuiți bigint cu float în a treia linie)

numerele Fibonacci:

Exemplu pentru Microsoft SQL Server 2005 , Microsoft SQL Server 2008 R2 , Microsoft SQL Server 2012

Este folosită o definiție iterativă a numerelor Fibonacci, implementată printr-o interogare recursivă. Fiecare linie a interogării conține două numere adiacente în succesiune, iar următoarea linie este calculată ca (ultimul număr, suma numerelor) al liniei anterioare. Astfel, toate numerele, cu excepția primului și ultimului, apar de două ori, astfel încât numai primele numere din fiecare rând sunt incluse în rezultat.

factorial:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

Acest exemplu demonstrează utilizarea instrucțiunii model, disponibilă începând cu Oracle 10g, care permite ca șirurile de interogări să fie tratate ca elemente de matrice. Fiecare linie conține două câmpuri - numărul liniei n și factorialul său f.

selectați n || „!=" || f factorial din modelul dual returnează toate dimensiunile rândurilor prin ( 0 d ) măsuri ( 0 f , 1 n ) reguli iterate (17 ) ( f [ număr_iterație ] = decodificare (număr_iterație , 0 , 1 , f [ număr_iterație - 1 ] * număr_iterație ) , n [ iteration_number ] = iteration_number );

numerele Fibonacci:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

Acest exemplu demonstrează utilizarea instrucțiunii model, disponibilă începând cu Oracle 10g, care permite ca șirurile de interogări să fie tratate ca elemente de matrice. Fiecare linie conține două câmpuri - numărul Fibonacci însuși și concatenarea tuturor numerelor mai mici sau egale cu acesta. Concatenarea iterativă a numerelor în aceeași interogare în care sunt generate este mai ușoară și mai rapidă decât agregarea ca operație independentă.

selectați max(uri) || ", ..." din (selectați s din modelul dual returnează toate dimensiunile rândurilor cu ( 0 d ) măsuri ( cast (" " ca varchar2 (200 )) s , 0 f ) regulile iterate (16 ) ( f [ iteration_number ] = decode (număr_iterație, 0, 1, 1, 1, f [număr_iterație - 1] + f [număr_iterație - 2]), s [număr_iterație] = decode (număr_iterație, 0, to_char (f [număr_iterație]), _număr [număr_iterație] 1 ] || ", " || to_char (f [ iteration_number ])) ) );

factorial:

Exemplu pentru versiunile MySQL 5

selectați concat (cast (t2 . n ca char ), "!= " , cast (exp (suma (log (t1 . n ))) ca char )) din ( selectați @ i := @ i + 1 AS n din TABLE , (selectați @ i := 0 ) ca limită sel1 16 ) t1 , ( selectați @ j : = @ j + 1 AS n din TABEL , (selectați @ j := 0 ) ca limită sel1 16 ) t2 unde t1 . n<= t2 . n group by t2 . n

numerele Fibonacci:

Exemplu pentru versiunile MySQL 5

Înlocuiți TABLE cu orice tabel pe care îl puteți accesa, cum ar fi mysql.help_topic .

selectați concat (group_concat (f separator ", " ), ", ..." ) din (selectați @ f := @ i + @ j ca f , @ i := @ j , @ j := @ f din TABLE , (selectați @ i := 1 , @ j := 0 ) sel1 limit 16 ) t

Salut Lume!:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

Acest exemplu folosește un bloc PL/SQL anonim care imprimă un mesaj la ieșirea standard folosind pachetul dbms_output.

începe dbms_output . put_line("Bună, lume!"); Sfârşit ;

factorial:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

Acest exemplu demonstrează calculul factorial iterativ folosind PL/SQL.

declara n numar := 0 ; fnumar := 1 ; începe în timp ce (n<= 16 ) loop dbms_output . put_line (n || "! = " || f ); n : = n + 1 ; f : = f * n ; end loop ; end ;

numerele Fibonacci:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

Acest exemplu folosește definiția iterativă a numerelor Fibonacci. Numerele deja calculate sunt stocate în structura de date varray, în mod analog cu o matrice.

vectorul de tip declarare este varray (16 ) de număr; fib vector := vector(); i număr; svarchar2(100); beginfib . extinde(16); fib (1 ) := 1 ; fib (2 ) := 1 ; s:=fib(1) || ", " || fib(2) || „, „; pentru i în 3 .. 16 buclă fib (i ) : = fib (i - 1 ) + fib (i - 2 ); s := s || fib(i) || „, „; buclă de capăt; dbms_output . put_line(s || "..." ); Sfârşit ;

Ecuație cuadratică:

Exemplu pentru Oracle 10g SQL, Oracle 11g SQL

Acest exemplu a fost testat cu SQL*Plus, TOAD și PL/SQL Developer.

Pure SQL vă permite să introduceți variabile în timpul execuției interogării ca variabile substituite. Pentru a defini o astfel de variabilă, numele acesteia (în acest caz A, B și C) trebuie folosit cu un ampersand și în fața acesteia de fiecare dată când variabila trebuie să fie referită. Când se execută o interogare, utilizatorului i se solicită să introducă valorile tuturor variabilelor înlocuite utilizate în interogare. După introducerea valorilor, fiecare referință la o astfel de variabilă este înlocuită cu valoarea acesteia, iar interogarea rezultată este executată.

Există mai multe moduri de a introduce valori pentru variabilele substituite. În acest exemplu, prima referință la fiecare variabilă este precedată de un ampersand dublu && în loc de un singur ampersand. Astfel, valoarea pentru fiecare variabilă este introdusă o singură dată, iar toate referințele ulterioare la aceasta vor fi înlocuite cu aceeași valoare (când se folosește un singur și în SQL*Plus, valoarea pentru fiecare referință la aceeași variabilă trebuie introdusă separat) . În PL/SQL Developer, referințele la toate variabilele trebuie să fie precedate de un singur & , altfel va apărea o eroare ORA-01008 „Nu toate variabilele sunt legate”.

Prima linie a exemplului specifică caracterul pentru separatorul zecimal, care este utilizat la convertirea numerelor rădăcină în șiruri.

Cererea în sine constă din patru cereri diferite. Fiecare interogare returnează un șir care conține rezultatul calculelor, într-unul dintre cazuri (A=0, D=0, D>0 și D<0) и ничего — в трех остальных случаях. Результаты всех четырех запросов объединяются, чтобы получить окончательный результат.

modifica setarea sesiunii NLS_NUMERIC_CHARACTERS = "." ; selectați „Nu este o ecuație pătratică”. și de la dual unde && A = 0 unire selectați "x = " || to_char (-&& B / 2 /& A ) din dual unde & A != 0 și & B *& B - 4 *& A *&& C = 0 unire selectează "x1 = " || to_char ((-& B + sqrt (& B *& B - 4 *& A *& C )) / 2 /& A ) || ", x2 = " || to_char (-& B - sqrt (& B *& B - 4 *& A *& C )) / 2 /& A din dual unde & A != 0 și & B *& B - 4 *& A *& C > 0 unire selectați „x1 = (" || to_char (-& B / 2 /& A ) || "," || to_char (sqrt (-& B *& B + 4 *& A *& C ) / 2 /& A ) || "), " || "x2 = (" || to_char (-& B / 2 /& A ) || "," || to_char (- sqrt (-& B *& B + 4 *& A *& C ) / 2 /& A ) || ")" din dual unde & A != 0 și & B *& B - 4 *& A *& C< 0 ;

Ultima actualizare: 24.06.2017

SQL Server este unul dintre cele mai populare sisteme de gestionare a bazelor de date (DBMS) din lume. Acest SGBD este potrivit pentru o varietate de proiecte: de la aplicații mici până la proiecte mari cu sarcină mare.

SQL Server a fost creat de Microsoft. Prima versiune a apărut în 1987. Iar versiunea actuală este versiunea 16, care a fost lansată în 2016 și va fi folosită în ghidul actual.

SQL Server a fost mult timp exclusiv un sistem de gestionare a bazelor de date pentru Windows, dar începând cu versiunea 16 acest sistem este disponibil și pe Linux.

SQL Server este caracterizat de caracteristici precum:

    Performanţă. SQL Server este foarte rapid.

    Fiabilitate și siguranță. SQL Server oferă criptarea datelor.

    Simplitate. Acest SGBD este relativ ușor de utilizat și de administrat.

Aspectul central în MS SQL Server, ca în orice SGBD, este baza de date. O bază de date este un depozit de date organizate într-un anumit mod. Nu este neobișnuit ca o bază de date să reprezinte fizic un fișier pe un hard disk, deși o astfel de mapare nu este necesară. Sistemele de management al bazelor de date sau SGBD-urile sunt folosite pentru a stoca și administra bazele de date. Și doar MS SQL Server este unul dintre astfel de SGBD.

MS SQL Server folosește un model relațional pentru a organiza bazele de date. Acest model de bază de date a fost dezvoltat în 1970 de către Edgar Codd. Și astăzi este de fapt standardul pentru organizarea bazelor de date.

Modelul relațional presupune stocarea datelor sub formă de tabele, fiecare dintre ele constând din rânduri și coloane. Fiecare rând stochează un obiect separat, iar coloanele conțin atributele acestui obiect.

O cheie primară este utilizată pentru a identifica fiecare rând dintr-un tabel. Cheia primară poate fi una sau mai multe coloane. Folosind cheia primară, ne putem referi la un anumit rând dintr-un tabel. În consecință, două rânduri nu pot avea aceeași cheie primară.

Prin chei, un tabel poate fi legat de altul, adică pot fi organizate legături între două tabele. Și tabelul în sine poate fi reprezentat ca o relație („relație”).

SQL (Structured Query Language) este folosit pentru a interacționa cu baza de date. Clientul (de exemplu, un program extern) trimite o solicitare în SQL folosind un API special. SGBD interpretează și execută în mod corespunzător cererea, apoi trimite rezultatul către client.

SQL a fost dezvoltat inițial de IBM pentru un sistem de baze de date numit System/R. În același timp, limba în sine a fost numită SEQUEL (Structured English Query Language). Deși nici baza de date, nici limba în sine nu au fost ulterior publicate oficial, în mod tradițional, termenul SQL în sine este adesea pronunțat ca „o continuare”.

În 1979, Relational Software Inc. a dezvoltat primul sistem de gestionare a bazelor de date, care se numea Oracle și care folosea limbajul SQL. Datorită succesului acestui produs, compania a fost redenumită Oracle.

Ulterior, au început să apară și alte sisteme de baze de date care foloseau SQL. Drept urmare, în 1989, Institutul Național American de Standarde (ANSI) a codificat limba și a publicat primul său standard. După aceea, standardul a fost actualizat și completat periodic. Ultima actualizare a avut loc în 2011. Dar, în ciuda existenței unui standard, furnizorii de DBMS folosesc adesea propriile implementări ale limbajului SQL, care sunt ușor diferite unele de altele.

Există două varietăți de limbaj SQL: PL-SQL și T-SQL. PL-SQL este utilizat în sistemele de baze de date precum Oracle și MySQL. T-SQL (Transact-SQL) este utilizat în SQL Server. De aceea, T-SQL va fi luat în considerare în cadrul ghidului actual.

În funcție de sarcina pe care o îndeplinește comanda T-SQL, aceasta poate fi unul dintre următoarele tipuri:

    DDL (Data Definition Language). Acest tip include diverse comenzi care creează o bază de date, tabele, indecși, proceduri stocate și așa mai departe. În general, datele sunt definite.

    În special, putem trimite următoarele comenzi la acest tip:

    • CREATE : creează obiecte de bază de date (baza de date însăși, tabele, indecși etc.)

      ALTER : Schimbă obiectele bazei de date

      DROP: elimină obiectele bazei de date

      TRUNCATE : elimină toate datele din tabele

    DML (Data Manipulation Language / Data Manipulation Language). Acest tip include comenzi pentru selectarea datelor, actualizarea acestora, adăugarea, ștergerea - în general, toate acele comenzi cu care putem gestiona datele.

    Acest tip include următoarele comenzi:

    • SELECT: preluați date din baza de date

      UPDATE: actualizează datele

      INSERT: adaugă date noi

      DELETE : șterge datele

    DCL (Data Control Language / Data Access Control Language). Acest tip include comenzi care gestionează drepturile de acces la date. În special, acestea sunt următoarele comenzi:

    • GRANT : acordă drepturi de acces la date

      REVOCA : revocă drepturile de acces la date

Funcționalitatea limbajului SQL

Principalele funcționalități ale limbajului SQL sunt prezentate mai jos.

Definirea datelor. Această funcție SQL este o descriere a structurii de date suportate și a organizării relațiilor relaționale (tabele). Pentru implementarea acestuia sunt destinati operatorii pentru crearea unei baze de date, crearea tabelelor si accesarea datelor.

Crearea bazei de date. Instrucțiunea CREATE DATABASE este utilizată pentru a crea o nouă bază de date. Structura instrucțiunilor specifică numele bazei de date care urmează să fie creată.

Crearea de tabele. Tabelul de bază este creat folosind instrucțiunea CREATE TABLE. Acest operator specifică numele câmpurilor, tipurile de date pentru acestea, lungimea (pentru unele tipuri de date). SQL utilizează următoarele tipuri de date:

INTEGER este un număr întreg;

CHAR - valoarea caracterului;

VARCHAR - valoarea caracterului, sunt stocate doar caracterele nevide;

DECIMAL - număr zecimal;

FLOAT - număr în virgulă mobilă;

DOUBLE PRECISION - virgulă flotantă de dublă precizie;

DATETIME - data și ora;

BOOL este o valoare booleană.

Declarația de creare a tabelului specifică restricții asupra valorilor coloanei și asupra tabelului. Posibilele restricții sunt prezentate în tabel. 4.8

Tabelul 4.8 Restricții privind datele definite

Pentru un model de date relaționale, este esențial să specificați o cheie străină (FOREIGNKEY). Când declarați chei străine, trebuie să impuneți constrângeri adecvate asupra coloanei, cum ar fi NOT NULL.

Într-o instrucțiune SQL, CHECK denotă constrângeri semantice care asigură integritatea datelor, cum ar fi limitarea setului de valori valide pentru o anumită coloană.

Nu puteți utiliza instrucțiunea create table de mai multe ori pe același tabel. Dacă, după crearea sa, s-au găsit inexactități în definiția sa, atunci se pot face modificări folosind instrucțiunea ALTER TABLE. Această declarație are scopul de a schimba structura unui tabel existent: puteți șterge sau adăuga un câmp la un tabel existent.

Manipulare de date. SQL permite unui utilizator sau unei aplicații să modifice conținutul unei baze de date prin inserarea de date noi, ștergerea sau modificarea datelor existente.

Inserarea de date noi este o procedură pentru adăugarea de rânduri la o bază de date și se realizează folosind instrucțiunea INSERT.

Modificarea datelor implică modificări ale valorilor într-una sau mai multe coloane ale unui tabel și se efectuează folosind instrucțiunea UPDATE. Exemplu:

SET suma=suma+1000,00

UNDE suma>0

Eliminarea rândurilor din tabel se face folosind instrucțiunea DELETE. Sintaxa operatorului este:

DE LA masă

Clauza WHERE este opțională, totuși, dacă nu este inclusă, atunci toate înregistrările din tabel vor fi șterse. Este util să folosiți instrucțiunea SELECT cu aceeași sintaxă ca și instrucțiunea DELETE pentru a verifica dinainte ce înregistrări vor fi șterse.

Asigurarea integritatii datelor. Limbajul SQL vă permite să definiți constrângeri de integritate destul de complexe, a căror satisfacție va fi verificată pentru toate modificările bazei de date. Controlul asupra rezultatelor tranzacțiilor, gestionarea erorilor care apar și coordonarea lucrului paralel cu baza de date a mai multor aplicații sau utilizatori este asigurat de instrucțiunile COMMIT (remediază încheierea cu succes a tranzacției curente și începutul uneia noi) și ROLLBACK necesitatea unei rollback - restaurarea automată a stării bazei de date la începutul tranzacției)

Eșantionarea datelor- una dintre cele mai importante funcții ale bazei de date, care corespunde instrucțiunii SELECT. Un exemplu de utilizare a operatorului a fost discutat în secțiunea anterioară.

În SQL, puteți crea secvențe imbricate de interogări (subinterogări). Există anumite tipuri de interogări care sunt cel mai bine implementate folosind subinterogări. Aceste interogări includ așa-numitele verificări ale existenței. Să presupunem că doriți să obțineți date despre studenții care nu au un scor de „șapte”. Dacă se returnează un set gol, atunci aceasta înseamnă un singur lucru - fiecare elev are cel puțin o astfel de evaluare.

Legătura de tabele. Instrucțiunile SQL vă permit să preluați date din mai mult de un tabel. O modalitate de a face acest lucru este să legați tabelele pe un singur câmp comun.

Instrucțiunea SELECT trebuie să conțină o restricție privind coincidența valorilor unei anumite coloane (câmp). Apoi numai acele rânduri în care se potrivesc valorile coloanei specificate vor fi preluate din tabelele aferente. Numele coloanei este indicat numai împreună cu numele tabelului; în caz contrar, operatorul va fi ambiguu.

Puteți utiliza alte tipuri de legături de tabele: operatorul INTER JOIN (inner join) asigură prezența în setul de înregistrări rezultat, potrivirea valorilor în câmpurile aferente. Îmbinările externe (OUTER JOIN) vă permit să includeți în rezultatul interogării toate rândurile dintr-un tabel și rândurile corespunzătoare din altul

Controlul accesului. SQL asigură sincronizarea procesării bazei de date de către diverse programe de aplicație, protecția datelor împotriva accesului neautorizat.

Accesul la date într-un mediu multi-utilizator este guvernat de declarațiile GRANT și REVOKE. În fiecare instrucțiune, trebuie să specificați utilizatorul, obiectul (tabel, vizualizare), în raport cu care sunt setate permisiunile și permisiunile în sine. De exemplu, instrucțiunea GRANT oferă utilizatorului X posibilitatea de a prelua date din tabelul PRODUCT:

Acordați SELECTAREA PE PRODUS LUI X

Declarația REVOKE revocă toate permisiunile acordate anterior.

Încorporarea SQL în programele de aplicație. Aplicațiile reale sunt de obicei scrise în alte limbi care generează cod SQL și îl transmit DBMS ca text ASCII.

Standardul IBM pentru produsele SQL specifică utilizarea SQL încorporat. Când scrieți un program de aplicație, textul acestuia este un amestec de comenzi ale limbajului principal de programare (de exemplu, C, Pascal, Cobol, Fortran, Assembler) și comenzi SQL cu un prefix special, de exemplu. ExecSQL. Structura instrucțiunilor SQL a fost extinsă pentru a se adapta variabilelor limbajului gazdă în constructele SQL.



Procesorul SQL modifică forma programului în conformitate cu cerințele compilatorului limbajului principal de programare. Funcția unui compilator este de a traduce (traduce) un program dintr-un limbaj de programare sursă într-un limbaj apropiat unui limbaj de mașină. După compilare, programul aplicat (aplicația) este un modul independent.

Dialecte SQL

În SGBD relațional modern, dialectele limbajului SQL sunt folosite pentru a descrie și manipula datele. Un subset al limbajului SQL care vă permite să creați și să descrieți o bază de date se numește DDL (Data Definition Language).

SQL a fost inițial numit SEQUEL (Structured English Query Language), apoi SEQUEL/2 și apoi doar SQL. Astăzi, SQL este standardul de facto pentru sistemele de management al bazelor de date relaționale.

Primul standard de limbaj a apărut în 1989 - SQL-89 și a fost susținut de aproape toate SGBD-urile relaționale comerciale. Era de natură generală și permitea o interpretare largă. Avantajele SQL-89 pot fi considerate standardizarea sintaxei și semanticii operatorilor de selecție și manipulare a datelor, precum și fixarea mijloacelor de limitare a integrității bazei de date. Cu toate acestea, lipsea o secțiune atât de importantă precum manipularea schemei bazei de date. Incompletitudinea standardului SQL-89 a dus la apariția în 1992 a următoarea versiune a limbajului SQL.

SQL2 (sau SQL-92) acoperă aproape tot ce aveți nevoie: manipularea schemei bazei de date, gestionarea tranzacțiilor și a sesiunilor, arhitecturi client-server sau instrumente de dezvoltare a aplicațiilor.

Următorul pas în dezvoltarea limbajului este varianta SQL 3. Această versiune a limbajului este completată de un mecanism de declanșare, definirea unui tip de date arbitrar și o extensie de obiect.

În prezent, există trei niveluri de limbă: începător, intermediar și complet. Mulți furnizori de baze de date folosesc propriile implementări de SQL, bazate cel puțin pe nivelul inițial al standardului ANSI relevant și care conțin unele extensii specifice unui anumit SGBD. În tabel. 4.9 prezintă exemple de dialecte SQL.

Tabelul 4.9 Dialecte SQL

SGBD Limbajul de interogare
Sistemul DBMS R SQL
DB2 SQL
Acces SQL
SYBASE SQL oriunde watcom-sql
SYBASE SQL Server Transact_SQL
MySQL SQL
Oracol PL/SQL

Bazele de date orientate pe obiecte folosesc limbajul de interogare obiect OQL (Object Query Language). Limbajul OQL s-a bazat pe comanda SQL2 SELECT și a adăugat capacitatea de a trimite o interogare către un obiect sau colecție de obiecte, precum și capacitatea de a apela metode într-o singură interogare.

Compatibilitatea multor dialecte SQL utilizate determină compatibilitatea DBMS. Astfel, SGBD-ul SYBASE SQL Anywhere este cât se poate de compatibil pentru un SGBD din această clasă cu SGBD-ul SYBASE SQL Server. Una dintre laturile acestei compatibilități este suportul în SYBASE SQL Anywhere a unui astfel de dialect al limbajului SQL precum Transact SQL. Acest dialect este folosit în SYBASE SQL Server și poate fi folosit în SYBASE SQL Anywhere împreună cu propriul său dialect al limbajului SQL - watcom-sql.

întrebări de testare

1. Cum poate fi clasificat un SGBD?

2. Ce modele de baze de date există?

3. Care sunt principalele elemente ale modelelor infologice?

4. Ce tipuri de relații există între entități?

5. Ce sunt diagramele ER și pentru ce sunt folosite?

6. Ce vă permite procedura de normalizare a tabelului?

7. Care sunt limbajul și instrumentele software ale SGBD?

8. Ce tip de SGBD este MS Access?

9. Care sunt principalele obiecte ale MS Access DBMS?

10. Pentru ce sunt folosite instrucțiunile SQL de bază?

Leran2002 9 aprilie 2015 la 12:31

Tutorial despre limbajul SQL (DDL, DML) folosind ca exemplu dialectul MS SQL Server. Prima parte

  • Microsoft SQL Server
  • SQL
  • tutorial

Despre ce este acest tutorial?

Acest tutorial este ceva ca o „ștampilă a memoriei mele” în limbajul SQL (DDL, DML), adică. acestea sunt informații care s-au acumulat în cursul activităților mele profesionale și sunt stocate constant în capul meu. Acesta este un minim suficient pentru mine, care este folosit cel mai des atunci când lucrez cu baze de date. Dacă apare nevoia de a folosi constructe SQL mai complete, atunci de obicei apelez la biblioteca MSDN aflată pe Internet pentru ajutor. În opinia mea, este foarte dificil să ții totul în cap și nu este nevoie în mod special de acest lucru. Dar cunoașterea construcțiilor de bază este foarte utilă, pentru că. sunt aplicabile aproape în aceeași formă în multe baze de date relaționale precum Oracle, MySQL, Firebird. Diferențele sunt în principal în tipurile de date, care pot diferi în detalii. Nu există atât de multe construcții de bază ale limbajului SQL și, cu o practică constantă, acestea sunt reținute rapid. De exemplu, pentru a crea obiecte (tabele, constrângeri, indexuri etc.) este suficient să aveți un editor de text al mediului (IDE) la îndemână pentru a lucra cu o bază de date și nu este nevoie să învățați un set de instrumente vizuale ascuțit pentru lucrul cu un anumit tip de bază de date (MS SQL, Oracle, MySQL, Firebird, …). Acest lucru este, de asemenea, convenabil, deoarece întregul text este în fața ochilor și nu trebuie să parcurgeți numeroase file pentru a crea, de exemplu, un index sau o restricție. Când lucrați constant cu baza de date, crearea, modificarea și mai ales re-crearea unui obiect folosind scripturi este de multe ori mai rapidă decât dacă se face în modul vizual. Tot în modul script (respectiv, cu atenția cuvenită), este mai ușor să stabiliți și să controlați regulile de denumire a obiectelor (parerea mea subiectivă). În plus, scripturile sunt convenabile de utilizat atunci când modificările făcute într-o bază de date (de exemplu, una de test) trebuie transferate în aceeași formă într-o altă bază de date (productivă).

Limbajul SQL este împărțit în mai multe părți, aici voi lua în considerare cele mai importante 2 părți ale acestuia:
  • DML - Data Manipulation Language (limbaj de manipulare a datelor), care conține următoarele constructe:
    • SELECT - selectarea datelor
    • INSERT - inserarea de date noi
    • UPDATE - actualizare de date
    • DELETE - ștergerea datelor
    • MERGE - fuziunea datelor
pentru că Sunt un practicant, ca atare va fi puțină teorie în acest manual și toate construcțiile vor fi explicate cu exemple practice. În plus, cred că un limbaj de programare, și mai ales SQL, poate fi stăpânit doar în practică, atingându-l singur și înțelegând ce se întâmplă atunci când executați cutare sau cutare construcție.

Acest tutorial a fost creat pe principiul Step by Step, adică. este necesar să o citim secvenţial şi de preferinţă imediat după exemple. Dar dacă pe parcurs trebuie să aflați despre o comandă mai detaliat, atunci utilizați o căutare specifică pe Internet, de exemplu, în biblioteca MSDN.

Când am scris acest tutorial, am folosit o bază de date MS SQL Server versiunea 2014 și am folosit MS SQL Server Management Studio (SSMS) pentru a rula scripturile.

Pe scurt despre MS SQL Server Management Studio (SSMS)

SQL Server Management Studio (SSMS) este un utilitar pentru Microsoft SQL Server pentru configurarea, gestionarea și administrarea componentelor bazei de date. Acest utilitar conține un editor de scripturi (pe care îl vom folosi în principal) și un program grafic care funcționează cu obiecte și setări de server. Instrumentul principal al SQL Server Management Studio este Object Explorer, care permite utilizatorului să vizualizeze, să preia și să gestioneze obiectele serverului. Acest text este parțial împrumutat de la Wikipedia.

Pentru a crea un nou editor de scripturi, utilizați butonul Interogare nouă:

Pentru a schimba baza de date curentă, puteți utiliza lista derulantă:

Pentru a executa o anumită comandă (sau un grup de comenzi), selectați-o și apăsați butonul „Execute” sau apăsați tasta „F5”. Dacă în editor există o singură comandă în acest moment sau dacă trebuie să executați toate comenzile, atunci nu trebuie să selectați nimic.

După executarea scripturilor, în special a celor care creează obiecte (tabele, coloane, indexuri), pentru a vedea modificările, utilizați Refresh din meniul contextual, evidențiind grupul corespunzător (de exemplu, Tabele), tabelul în sine sau grupul Coloane din acesta .

De fapt, acesta este tot ce trebuie să știm pentru a completa exemplele prezentate aici. Restul utilitarului SSMS este ușor de învățat pe cont propriu.

Un pic de teorie

O bază de date relațională (RDB, sau mai departe în contextul unei baze de date) este o colecție de tabele interconectate. În linii mari, o bază de date este un fișier în care datele sunt stocate într-o formă structurată.

DBMS - Sistemul de gestionare a acestor baze de date, de ex. acesta este un set de instrumente pentru lucrul cu un anumit tip de bază de date (MS SQL, Oracle, MySQL, Firebird, ...).

Notă
pentru că în viață, în vorbirea colocvială, spunem mai ales: „Oracle DB”, sau chiar doar „Oracle”, însemnând de fapt „Oracle DBMS”, apoi în contextul acestui tutorial se va folosi uneori termenul DB. Din context, cred că va fi clar ce anume este în joc.

Un tabel este o colecție de coloane. Coloanele pot fi numite și câmpuri sau coloane, toate aceste cuvinte vor fi folosite ca sinonime, exprimând același lucru.

Tabelul este obiectul principal al RDB, toate datele RDB sunt stocate linie cu linie în coloanele tabelului. Liniile, înregistrările sunt, de asemenea, sinonime.

Pentru fiecare tabel, precum și coloanele sale, sunt date nume, după care se face referire la acestea.
Numele obiectului (numele tabelului, numele coloanei, numele indexului etc.) în MS SQL poate avea o lungime maximă de 128 de caractere.

Pentru trimitere– în baza de date ORACLE, numele obiectelor pot avea o lungime maximă de 30 de caractere. Prin urmare, pentru o anumită bază de date, trebuie să vă dezvoltați propriile reguli pentru denumirea obiectelor pentru a îndeplini limita numărului de caractere.

SQL este un limbaj care vă permite să interogați baza de date prin intermediul SGBD. Într-un anumit SGBD, limbajul SQL poate avea o implementare specifică (propul său dialect).

DDL și DML sunt un subset al limbajului SQL:

  • Limbajul DDL este folosit pentru a crea și modifica structura bazei de date, de ex. pentru a crea/modifica/sterge tabele si relatii.
  • Limbajul DML vă permite să manipulați datele din tabel, de ex. cu replicile ei. Vă permite să selectați date din tabele, să adăugați date noi în tabele și să actualizați și să ștergeți datele existente.

În limbajul SQL, puteți utiliza 2 tipuri de comentarii (pe o singură linie și pe mai multe rânduri):

Comentariu pe o singură linie
și

/* comentariu pe mai multe linii */

De fapt, totul pentru teoria acestui lucru va fi suficient.

DDL - Data Definition Language (limbaj de descriere a datelor)

De exemplu, luați în considerare un tabel cu date despre angajați, sub forma familiară unei persoane care nu este programator:

În acest caz, coloanele din tabel au următoarele nume: Număr de personal, Nume complet, Data nașterii, E-mail, Funcție, Departament.

Fiecare dintre aceste coloane poate fi caracterizată prin tipul de date pe care le conține:

  • Număr de personal - număr întreg
  • nume complet - șir
  • Data nașterii - data
  • E-mail - șir
  • Poziție - șir
  • departament – ​​sfoară
Tipul de coloană este o caracteristică care indică ce fel de date poate stoca această coloană.

Pentru început, va fi suficient să ne amintim doar următoarele tipuri de date de bază utilizate în MS SQL:

Sens Notare în MS SQL Descriere
Șir de lungime variabilă varchar(N)
și
nvarchar(N)
Cu numărul N, putem specifica lungimea maximă posibilă a șirului pentru coloana corespunzătoare. De exemplu, dacă vrem să spunem că valoarea coloanei „Nume” poate conține maximum 30 de caractere, atunci trebuie să setăm tipul acesteia la nvarchar (30).
Diferența dintre varchar și nvarchar este că varchar vă permite să stocați șiruri în format ASCII, unde un caracter ocupă 1 octet, în timp ce nvarchar stochează șiruri în format Unicode, unde fiecare caracter ocupă 2 octeți.
Tipul varchar ar trebui folosit numai dacă sunteți 100% sigur că câmpul nu va trebui să stocheze caractere Unicode. De exemplu, varchar poate fi folosit pentru a stoca adrese de e-mail, deoarece de obicei conțin doar caractere ASCII.
Snur de lungime fixă char(N)
și
nchar(N)
Acest tip diferă de un șir de lungime variabilă prin faptul că, dacă lungimea șirului este mai mică de N caractere, atunci este întotdeauna completat la dreapta la lungimea de N spații și stocat în baza de date sub această formă, de exemplu. în baza de date ocupă exact N caractere (unde un caracter ocupă 1 octet pentru char și 2 octeți pentru nchar). În practica mea, acest tip este foarte rar folosit, iar dacă este folosit, atunci este folosit în principal în formatul char (1), adică. când câmpul este definit de un singur caracter.
Întreg int Acest tip ne permite să folosim numai numere întregi, atât pozitive, cât și negative, în coloană. Pentru referință (acest lucru nu este atât de relevant pentru noi acum) - intervalul de numere pe care tipul int îl permite de la -2 147 483 648 la 2 147 483 647. Acesta este de obicei tipul principal care este folosit pentru a seta identificatorii.
Număr real sau real pluti În termeni simpli, acestea sunt numere în care poate fi prezentă un punct zecimal (virgulă).
data Data Dacă coloana trebuie să stocheze doar Data, care constă din trei componente: Număr, Lună și An. De exemplu, 15.02.2014 (15.02.2014). Acest tip poate fi folosit pentru coloana „Data admiterii”, „Data nașterii”, etc., adică. în cazurile în care este important pentru noi să fixăm doar data, sau când componenta de timp nu este importantă pentru noi și poate fi aruncată sau dacă nu este cunoscută.
Timp timp Acest tip poate fi utilizat dacă coloana trebuie să stocheze numai date de timp, de exemplu. Ore, minute, secunde și milisecunde. De exemplu, 17:38:31.3231603
De exemplu, „Ora de plecare a zborului” zilnică.
data si ora datetime Acest tip vă permite să stocați atât data, cât și ora în același timp. De exemplu, 02/15/2014 5:38:31.323 PM
De exemplu, aceasta ar putea fi data și ora unui eveniment.
Steag pic Acest tip este util pentru stocarea valorilor Da/Nu, unde Da va fi stocat ca 1 și Nu va fi stocat ca 0.

De asemenea, valoarea câmpului, în cazul în care nu este interzis, poate să nu fie specificată, în acest scop fiind folosit cuvântul cheie NULL.

Pentru a rula exemplele, să creăm o bază de date de testare numită Test.

O bază de date simplă (fără a specifica parametri suplimentari) poate fi creată prin rularea următoarei comenzi:

Test CREATE DATABASE
Puteți șterge baza de date cu comanda (ar trebui să fiți foarte atenți cu această comandă):

Testul DROP DATABASE
Pentru a trece la baza noastră de date, puteți rula comanda:

Testul SUA
Alternativ, selectați baza de date Test din lista derulantă din zona de meniu SSMS. La serviciu, folosesc adesea această metodă de comutare între baze de date.

Acum în baza noastră de date putem crea un tabel folosind descrierile așa cum sunt, folosind spații și caractere chirilice:

CREATE TABLE [Angajați]([Număr de personal] int, [Nume] nvarchar(30), [Data nașterii] data, nvarchar(30), [Posiție] nvarchar(30), [Departament] nvarchar(30))
În acest caz, va trebui să introducem numele între paranteze drepte […].

Dar în baza de date, pentru o mai mare comoditate, este mai bine să specificați toate numele obiectelor în latină și să nu folosiți spații în nume. În MS SQL, de obicei, în acest caz, fiecare cuvânt începe cu o literă mare, de exemplu, pentru câmpul „Număr de personal”, am putea seta numele NumărPersonal. De asemenea, puteți utiliza numere în nume, de exemplu, PhoneNumber1.

Pe o notă
În unele DBMS, următorul format de nume „PHONE_NUMBER” poate fi mai preferabil, de exemplu, acest format este adesea folosit în baza de date ORACLE. Desigur, la setarea numelui câmpului, este de dorit ca acesta să nu se potrivească cu cuvintele cheie utilizate în SGBD.

Din acest motiv, puteți uita de sintaxa parantezei drepte și puteți șterge tabelul [Angajați]:

DROP TABLE [Angajați]
De exemplu, un tabel cu angajați poate fi numit „Angajați”, iar câmpurile sale pot primi următoarele nume:

  • ID - Număr de personal (ID de angajat)
  • Nume - nume complet
  • Ziua de naștere - Data nașterii
  • E-mail
  • Poziţie
  • Departament - Departament
Foarte des, cuvântul ID este folosit pentru a denumi câmpul de identificare.

Acum să creăm tabelul nostru:

CREATE TABLE Angajații (ID int, Nume nvarchar(30), Data nașterii, Email nvarchar(30), Poziția nvarchar(30), Departament nvarchar(30))
Puteți utiliza opțiunea NOT NULL pentru a specifica coloanele necesare.

Pentru un tabel deja existent, câmpurile pot fi redefinite folosind următoarele comenzi:

Actualizați câmpul ID ALTER TABLE Angajații ALTER COLUMN ID int NOT NULL -- update Nume câmp ALTER TABLE Angajații ALTER COLUMN Nume nvarchar(30) NOT NULL

Pe o notă
Conceptul general al limbajului SQL pentru majoritatea SGBD-urilor rămâne același (cel puțin, pot judeca acest lucru din acele SGBD-uri cu care am avut șansa să lucrez). Diferența dintre DDL în diferite SGBD-uri constă în principal în tipurile de date (nu doar numele lor pot diferi aici, ci și detaliile implementării lor), însăși specificul implementării limbajului SQL poate diferi ușor (adică esența comenzile este aceeași, dar pot exista mici diferențe în dialect, din păcate, dar nu există un singur standard). Cunoscând elementele de bază ale SQL, puteți trece cu ușurință de la un SGBD la altul. în acest caz, va trebui doar să înțelegeți detaliile implementării comenzilor în noul SGBD, de exemplu. în cele mai multe cazuri, va fi suficient doar să faci o analogie.

Crearea unui tabel CREATE TABLE Angajații (ID int, -- în ORACLE, tipul int este echivalentul (învelișului) pentru numărul (38) Nume nvarchar2(30), -- nvarchar2 în ORACLE este echivalent cu nvarchar în MS SQL Data nașterii, e-mail nvarchar2 (30) , Poziția nvarchar2(30), Departamentul nvarchar2(30)); -- actualizarea câmpurilor ID și Nume (aici MODIFY(…) este folosită în loc de ALTER COLUMN ALTER TABLE Angajații MODIFY(ID int NOT NULL,Name nvarchar2(30) NOT NULL); -- adăugarea unui PK (în acest caz, construcția arată ca în MS SQL, va fi afișată mai jos) ALTER TABLE Angajații ADD CONSTRAINT PK_Employees PRIMARY KEY(ID);
Pentru ORACLE, există diferențe în ceea ce privește implementarea tipului varchar2, codificarea acestuia depinde de setările bazei de date și textul poate fi salvat, de exemplu, în codificare UTF-8. În plus, lungimea câmpului în ORACLE poate fi setată atât în ​​octeți, cât și în caractere, pentru aceasta se folosesc opțiuni suplimentare BYTE și CHAR, care sunt specificate după lungimea câmpului, de exemplu:

NAME varchar2(30 BYTE) -- capacitatea câmpului va fi de 30 de octeți NAME varchar2(30 CHAR) -- capacitatea câmpului va fi de 30 de caractere
Ce optiune va fi folosita implicit BYTE sau CHAR, in cazul unei specificari simple de tip varchar2(30) in ORACLE, depinde de setarile bazei de date, poate fi setata uneori si in setarile IDE. În general, uneori te poți încurca cu ușurință, așa că în cazul ORACLE, dacă se folosește tipul varchar2 (și uneori acest lucru este justificat aici, de exemplu, când folosești codificarea UTF-8), prefer să scriu în mod explicit CHAR (pentru că de obicei este mai convenabil să citiți lungimea unui șir în caractere).

Dar în acest caz, dacă există deja unele date în tabel, atunci pentru executarea cu succes a comenzilor, este necesar ca câmpurile ID și Nume din toate rândurile tabelului să fie completate. Să demonstrăm acest lucru cu un exemplu, să inserăm date în tabel în câmpurile ID, Poziție și Departament, acest lucru se poate face cu următorul script:

INSERT Angajații (ID, Poziție, Departament) VALORI (1000,N"Director",N"Administrație"), (1001,N"Programator",N"IT"), (1002,N"Contabil", N"Contabilitate" ), (1003,N"Programator senior",N"IT")
În acest caz, comanda INSERT va arunca și o eroare, deoarece la inserare, nu am specificat valoarea câmpului obligatoriu Nume.
În cazul în care aveam deja aceste date în tabelul original, atunci comanda „ALTER TABLE Employees ALTER COLUMN ID int NOT NULL” ar avea succes, iar comanda „ALTER TABLE Employees ALTER COLUMN Name int NOT NULL” ar emite o eroare mesaj, că există valori NULL (nespecificate) în câmpul Nume.

Să adăugăm valori pentru câmpul Nume și să completăm din nou datele:


De asemenea, opțiunea NOT NULL poate fi utilizată direct la crearea unui tabel nou, adică. în contextul comenzii CREATE TABLE.

Mai întâi, ștergeți tabelul cu comanda:

DROP TABLE Angajații
Acum să creăm un tabel cu coloanele obligatorii ID și Nume:

CREATE TABLE Angajații (ID int NU NULL, Nume nvarchar(30) NU NULL, Data nașterii, E-mail nvarchar(30), Poziția nvarchar(30), Departament nvarchar(30))
De asemenea, puteți scrie NULL după numele coloanei, ceea ce va însemna că valorile NULL (nespecificate) vor fi permise în ea, dar acest lucru nu este necesar, deoarece această caracteristică este implicită implicită.

Dacă, dimpotrivă, doriți să faceți opțională o coloană existentă, atunci utilizați următoarea sintaxă a comenzii:

ALTER TABLE Angajații ALTER COLUMN Nume nvarchar(30) NULL
Sau pur și simplu:

ALTER TABLE Angajații ALTER COLUMN Nume nvarchar(30)
Cu această comandă, putem, de asemenea, să schimbăm tipul câmpului cu un alt tip compatibil sau să-i schimbăm lungimea. De exemplu, să extindem câmpul Nume la 50 de caractere:

ALTER TABLE Angajații ALTER COLUMN Nume nvarchar(50)

cheia principala

La crearea unui tabel, este de dorit ca acesta să aibă o coloană unică sau un set de coloane unic pentru fiecare dintre rândurile sale - o înregistrare poate fi identificată în mod unic prin această valoare unică. Această valoare se numește cheia primară a tabelului. Pentru tabelul nostru Angajați, această valoare unică ar putea fi coloana ID (care conține „Numărul personalului angajat” – chiar dacă în cazul nostru această valoare este unică pentru fiecare angajat și nu poate fi repetată).

Puteți crea o cheie primară pentru un tabel existent utilizând comanda:

ALTER TABLE Angajații ADD CONSTRAINT PK_Angajații CHEIE PRIMĂRĂ(ID)
Unde „PK_Angajați” este numele constrângerii responsabile pentru cheia primară. De obicei, cheia primară este numită cu prefixul „PK_” urmat de numele tabelului.

Dacă cheia primară constă din mai multe câmpuri, atunci aceste câmpuri trebuie listate între paranteze separate prin virgule:

ALTER TABLE nume_tabel ADD CONSTRAINT nume_constrângere PRIMARY KEY(câmp1, câmp2,...)
Este de remarcat faptul că în MS SQL toate câmpurile care sunt incluse în cheia primară trebuie să aibă caracteristica NOT NULL.

De asemenea, cheia primară poate fi definită direct la crearea unui tabel, adică în contextul comenzii CREATE TABLE. Să ștergem tabelul:

DROP TABLE Angajații
Și apoi creați-l folosind următoarea sintaxă:

CREATE TABLE Angajații(ID int NU NUL, Nume nvarchar(30) NU NULL, data nașterii, e-mail nvarchar(30), Poziția nvarchar(30), Departament nvarchar(30), CONSTRAINT PK_Employees PRIMARY KEY(ID) -- descrieți PK după toate câmpurile ca o constrângere)
După creare, completați datele din tabel:

INSERT Angajații (ID, Poziție, Departament, Nume) VALORI (1000,N"Director",N"Administrație",N"Ivanov II.), (1001,N"Programator",N"IT",N" Petrov P.P." ), (1002,N"Contabil",N"Contabilitate",N"Sidorov S.S.", (1003,N"Programator senior",N"IT",N"Andreev A. DAR")
Dacă cheia primară din tabel constă numai din valorile unei coloane, atunci se poate folosi următoarea sintaxă:

CREATE TABLE Angajații(ID int NOT NULL CONSTRAINT PK_Employees PRIMARY KEY, -- specificați Nume nvarchar(30) NOT NULL, Data nașterii, E-mail nvarchar(30), Poziție nvarchar(30), Departament nvarchar(30))
De fapt, numele constrângerii poate fi omis, caz în care i se va da un nume de sistem (cum ar fi „PK__Employee__3214EC278DA42077”):

CREATE TABLE Angajații(ID int NU NULL, Nume nvarchar(30) NU NULL, Data nașterii, E-mail nvarchar(30), Poziția nvarchar(30), Departament nvarchar(30), CHEIE PRIMARIA (ID))
Sau:

CREATE TABLE Angajații (ID int NOT NULL CHEIE PRIMARĂ, Nume nvarchar(30) NU NULL, Data nașterii, E-mail nvarchar(30), Poziția nvarchar(30), Departament nvarchar(30))
Dar aș recomanda să setați întotdeauna în mod explicit numele constrângerii pentru tabelele permanente, deoarece printr-un nume dat în mod explicit și ușor de înțeles, ulterior va fi mai ușor să îl manipulați, de exemplu, îl puteți șterge:

ALTER TABLE Angajații DROP CONSTRAINT PK_Angajați
Dar o astfel de sintaxă scurtă, fără a specifica numele restricțiilor, este convenabilă de utilizat atunci când se creează tabele de baze de date temporare (numele unui tabel temporar începe cu # sau ##), care vor fi șterse după utilizare.

Să rezumam

Până acum am acoperit următoarele comenzi:
  • CREAȚI TABEL table_name (enumerarea câmpurilor și a tipurilor acestora, restricții) - folosit pentru a crea un nou tabel în baza de date curentă;
  • DROP TABLE table_name - folosit pentru a șterge un tabel din baza de date curentă;
  • ALTER TABLE nume_tabel ALTER COLONA nume_coloană … – folosit pentru a actualiza tipul coloanei sau pentru a modifica setările acesteia (de exemplu, pentru a seta caracteristica NULL sau NOT NULL);
  • ALTER TABLE nume_tabel ADĂUGAȚI CONSTRINGERE nume_constrângere CHEIA PRINCIPALA(câmp1, câmp2,...) – adăugarea unei chei primare la un tabel existent;
  • ALTER TABLE nume_tabel CONSTRINGERE DE CĂDERARE constraint_name - eliminați constrângerea din tabel.

Câteva despre mesele temporare

Decuparea din MSDN. Există două tipuri de tabele temporare în MS SQL Server: locale (#) și globale (##). Tabelele temporare locale sunt vizibile numai pentru creatorii lor până când sesiunea de conectare cu instanța SQL Server este încheiată odată ce sunt create pentru prima dată. Tabelele temporare locale sunt șterse automat după ce un utilizator se deconectează de la o instanță a SQL Server. Tabelele temporare globale sunt vizibile pentru toți utilizatorii în timpul oricăror sesiuni de conexiune după crearea acestor tabele și sunt șterse atunci când toți utilizatorii care fac referire la aceste tabele se deconectează de la instanța SQL Server.

Tabelele temporare sunt create în baza de date a sistemului tempdb, de exemplu. creând-le, nu înfundam baza de date principală, altfel tabelele temporare sunt complet identice cu tabelele obișnuite, ele pot fi șterse și folosind comanda DROP TABLE. Tabelele temporare locale (#) sunt mai frecvent utilizate.

Pentru a crea un tabel temporar, puteți folosi comanda CREATE TABLE:

CREATE TABLE #Temp(ID int, Nume nvarchar(30))
Deoarece un tabel temporar în MS SQL este similar cu un tabel obișnuit, îl puteți șterge în consecință cu comanda DROP TABLE:

DROP TABLE #Temp

De asemenea, puteți crea un tabel temporar (precum și un tabel obișnuit) și îl puteți completa imediat cu datele returnate de interogare folosind sintaxa SELECT ... INTO:

SELECT ID, Nume INTO #Temp FROM Angajati

Pe o notă
În diferite SGBD, implementarea tabelelor temporare poate diferi. De exemplu, în DBMS-ul ORACLE și Firebird, structura tabelelor temporare trebuie definită în prealabil cu comanda CREATE GLOBAL TEMPORARY TABLE, indicând specificul stocării datelor în acesta, apoi utilizatorul o vede printre tabelele principale și lucrează cu ea. ca la o masă obișnuită.

Normalizarea bazei de date - împărțirea în sub-tabele (directoare) și determinarea relațiilor

Tabelul nostru actual de angajați are dezavantajul că utilizatorul poate introduce orice text în câmpurile Poziție și Departament, care este în primul rând plin de erori, deoarece pentru un angajat poate indica pur și simplu „IT” ca departament, iar pentru al doilea angajat, pentru exemplu , introduceți „departamentul IT”, aveți al treilea „IT”. Ca urmare, nu va fi clar ce a vrut să spună utilizatorul, adică. Acești angajați sunt angajați ai aceluiași departament sau s-a descris utilizatorul și acestea sunt 3 departamente diferite? Și cu atât mai mult, în acest caz, nu vom putea grupa corect datele pentru un raport, unde ar putea fi necesar să se arate numărul de angajați în contextul fiecărui departament.

Al doilea dezavantaj este cantitatea de stocare a acestor informații și duplicarea acesteia, adică. pentru fiecare angajat este indicat numele complet al departamentului, ceea ce necesită un loc în baza de date pentru a stoca fiecare caracter din numele departamentului.

Al treilea dezavantaj este dificultatea actualizării acestor câmpuri dacă numele unei poziții se schimbă, de exemplu, dacă trebuie să redenumiți poziția „Programator” în „Programator junior”. În acest caz, va trebui să facem modificări la fiecare linie a tabelului, în care Poziția este egală cu „Programator”.

Pentru a evita aceste neajunsuri, se folosește așa-numita normalizare a bazei de date - împărțirea acesteia în sub-tabele, tabele de referință. Nu este necesar să urci în jungla teoriei și să studiezi ce sunt formele normale, este suficient să înțelegem esența normalizării.

Să creăm 2 tabele de referință „Poziții” și „Departamente”, primul se va numi Posturi, iar cel de-al doilea, respectiv, Departamente:

CREATE TABLE Poziții(ID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Positions CHEIE PRIMARĂ, Nume nvarchar(30) NOT NULL) CREATE TABLE Departamente(ID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Departments CHEIE PRIMARĂ, Nume nvarchar(30) ) NU NUL)
Rețineți că aici am folosit noua opțiune IDENTITATE, ceea ce înseamnă că datele din coloana ID vor fi numerotate automat, începând de la 1, cu un pas de 1, adică. atunci când sunt adăugate înregistrări noi, li se vor atribui succesiv valorile 1, 2, 3 și așa mai departe. Astfel de câmpuri sunt de obicei numite auto-incrementare. Un singur câmp cu proprietatea IDENTITATE poate fi definit într-un tabel și, de obicei, dar nu neapărat, un astfel de câmp este cheia primară pentru acel tabel.

Pe o notă
În diferite SGBD, implementarea câmpurilor cu contor se poate face diferit. În MySQL, de exemplu, un astfel de câmp este definit folosind opțiunea AUTO_INCREMENT. În ORACLE și Firebird, această funcționalitate ar putea fi emulată anterior folosind SEQUENCE. Dar din câte știu, ORACLE a adăugat acum opțiunea GENERATE CA IDENTITATE.

Să completăm automat aceste tabele, pe baza datelor curente înregistrate în câmpurile Poziție și Departament din tabelul Angajați:

Completați câmpul Nume din tabelul Poziții cu valori unice din câmpul Poziție din tabelul Angajați INSERT Posiții (Nume) SELECTARE DISTINCT Poziția FROM Angajații WHERE Poziția NU ESTE NUL -- eliminați înregistrările fără nicio poziție specificată
Vom face același lucru pentru tabelul Departamente:

INSERT Departments(Nume) SELECT DISTINCT Department FROM Angajații WHERE Departamentul NU ESTE NUL
Dacă deschidem acum tabelele Poziții și Departamente, vom vedea un set numerotat de valori după câmpul ID:

SELECTAȚI * FROM Poziții

SELECT * FROM Departamente

Aceste tabele vor juca acum rolul de directoare pentru stabilirea posturilor și departamentelor. Ne vom referi acum la ID-urile postului și departamentului. În primul rând, să creăm noi câmpuri în tabelul Angajați pentru a stoca datele ID:

Adăugați câmp pentru ID-ul poziției ALTER TABLE Angajații ADD PositionID int -- adăugați câmp pentru ID-ul departamentului ALTER TABLE Angajații ADD DepartmentID int
Tipul câmpurilor de referință trebuie să fie același ca în directoare, în acest caz este int.

De asemenea, puteți adăuga mai multe câmpuri la tabel simultan cu o singură comandă, listând câmpurile separate prin virgule:

ALTER TABLE Angajații ADD PositionID int, DepartmentID int
Acum să scriem link-uri (constrângeri de referință - CHEIE străină) pentru aceste câmpuri, astfel încât utilizatorul să nu aibă posibilitatea de a scrie în aceste câmpuri, valori care nu se află printre valorile ID din directoare.

ALTER TABLE Angajații ADD CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositionID) REFERINȚE Poziții(ID)
Și vom face același lucru pentru al doilea câmp:

ALTER TABLE Angajații ADD CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(DepartmentID) REFERINȚE Departamente(ID)
Acum, utilizatorul va putea introduce în aceste câmpuri numai valorile ID din cartea de referință corespunzătoare. În consecință, pentru a utiliza un nou departament sau poziție, va trebui mai întâi să adauge o nouă intrare în directorul corespunzător. pentru că pozițiile și departamentele sunt acum stocate în directoare într-o singură copie, apoi pentru a schimba numele, este suficient să îl schimbați doar în director.

Numele constrângerii referențiale este de obicei compus, este format din prefixul „FK_”, urmat de numele tabelului, iar după liniuță, vine numele câmpului care se referă la identificatorul tabelului de căutare.

Identificatorul (ID) este de obicei o valoare internă care este folosită numai pentru legături și ce valoare este stocată acolo, în cele mai multe cazuri, este absolut indiferent, deci nu este nevoie să încerci să scapi de găurile din succesiunea numerelor care apar în timpul lucrului cu un tabel, de exemplu, după ștergerea înregistrărilor din manual.

ALTER TABLE table ADD CONSTRAINT constraint_name FOREIGN KEY(câmp1, câmp2,…) REFERINȚE tabel de căutare (câmp1, câmp2,…)
În acest caz, în tabelul „table_reference”, cheia primară este reprezentată de o combinație de mai multe câmpuri (câmp1, câmp2, ...).

De fapt, acum să actualizăm câmpurile PositionID și DepartmentID cu valorile ID din directoare. Să folosim comanda UPDATE DML în acest scop:

UPDATE e SET PositionID=(SELECT ID FROM Poziții WHERE Nume=e.Posiție), DepartmentID=(SELECT ID FROM Departments WHERE Nume=e.Department) FROM Angajați e
Să vedem ce se întâmplă rulând interogarea:

SELECTAȚI * FROM Angajați

Gata, câmpurile PositionID și DepartmentID sunt completate cu posturile și departamentele corespunzătoare cu ID-uri de nevoie în câmpurile Poziție și Departament din tabelul Angajați acum, puteți șterge aceste câmpuri:

ALTER TABLE Angajații DROP COLUMN Poziția, Departamentul
Tabelul arată acum așa:

SELECTAȚI * FROM Angajați

ID Nume Zi de nastere E-mail ID poziție ID departament
1000 Ivanov I.I. NUL NUL 2 1
1001 Petrov P.P. NUL NUL 3 3
1002 Sidorov S.S. NUL NUL 1 2
1003 Andreev A.A. NUL NUL 4 3

Acestea. în cele din urmă am scăpat de stocarea informațiilor redundante. Acum, după numerele de poziție și departament, le putem determina în mod unic numele folosind valorile din tabelele de căutare:

SELECT e.ID,e.Name,p.Name PositionName,d.Name DepartmentName FROM Angajați e LEFT JOIN Departamente d ON d.ID=e.DepartmentID LEFT JOIN Poziții p ON p.ID=e.PositionID

În Object Inspector, putem vedea toate obiectele create pentru un anumit tabel. De aici puteți efectua și diverse manipulări cu aceste obiecte - de exemplu, redenumiți sau ștergeți obiecte.

De asemenea, este de remarcat faptul că un tabel se poate referi la el însuși, de ex. puteți crea un link recursiv. De exemplu, să adăugăm un alt câmp ManagerID la tabelul nostru cu angajați, care va indica angajatul căruia îi raportează acest angajat. Să creăm un câmp:

ALTER TABLE Angajații ADD ManagerID int
Valoarea NULL este permisă în acest câmp, câmpul va fi gol dacă, de exemplu, nu există superiori peste angajat.

Acum să creăm o CHEIE STRĂINĂ pe tabelul Angajați:

ALTER TABLE Angajații ADD CONSTRAINT FK_Employees_ManagerID CHEIE STRĂINĂ (ManagerID) REFERINȚE Angajații (ID)
Să creăm acum o diagramă și să vedem cum arată relațiile dintre tabelele noastre pe ea:

Ca urmare, ar trebui să vedem următoarea imagine (tabelul Angajații este legat de tabelele Poziții și Departamente și se referă și la sine):

În cele din urmă, este de menționat că cheile de referință pot include opțiuni suplimentare ON DELETE CASCADE și ON UPDATE CASCADE, care indică cum să se comportă la ștergerea sau actualizarea unei înregistrări la care se face referire în tabelul de căutare. Dacă aceste opțiuni nu sunt specificate, atunci nu putem schimba ID-ul din tabelul de director al intrării care are legături din alt tabel și nici nu putem șterge o astfel de intrare din director până când nu ștergem toate rândurile care se referă la această intrare sau, actualizați aceste linii de referință la o altă valoare.

De exemplu, să recreăm tabelul cu opțiunea ON DELETE CASCADE pentru FK_Employees_DepartmentID:

DROP TABLE Angajații CREATE TABLE Angajații(ID int NOT NULL, Nume nvarchar(30), Data nașterii, Email nvarchar(30), PositionID int, DepartmentID int, ManagerID int, CONSTRAINT PK_Employees PRIMARY KEY (ID), CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY ) REFERINȚE Departamente(ID) ON DELETE CASCADE, CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositionID) REFERINȚE Poziții(ID), CONSTRAINT FK_Employees_ManagerID FOREIGN KEY (ManagerID) REFERINȚE Employees(ID)Nameye) )VALORI (1000,N"Ivanov I.I.","19550219",2,1,NULL), (1001,N"Petrov P.P.","19831203",3,3,1003), (1002 ,N"Sidorov S.S." ,"19760607",1,2,1000), (1003,N"Andreev A.A.","19820417",4,3,1000)
Să eliminăm departamentul cu ID 3 din tabelul Departamente:

DELETE Departamentele WHERE ID=3
Să ne uităm la datele din tabelul Angajații:

SELECTAȚI * FROM Angajați

ID Nume Zi de nastere E-mail ID poziție ID departament ID manager
1000 Ivanov I.I. 1955-02-19 NUL 2 1 NUL
1002 Sidorov S.S. 1976-06-07 NUL 1 2 1000

După cum puteți vedea, datele pentru departamentul 3 au fost și ele șterse din tabelul Angajați.

Opțiunea ON UPDATE CASCADE se comportă în mod similar, dar are efect la actualizarea valorii ID din director. De exemplu, dacă schimbăm ID-ul poziției în directorul de poziții, atunci în acest caz DepartmentID din tabelul Angajați va fi actualizat la noua valoare ID pe care am setat-o ​​în director. Dar în acest caz, pur și simplu nu va fi posibil să se demonstreze acest lucru, deoarece. coloana ID din tabelul Departamente are opțiunea IDENTITATE, care ne va împiedica să executăm următoarea interogare (schimbați ID-ul departamentului 3 în 30):

UPDATE Departamente SET ID=30 WHERE ID=3
Principalul lucru este să înțelegeți esența acestor 2 opțiuni ON DELETE CASCADE și ON UPDATE CASCADE. Folosesc aceste opțiuni în ocazii foarte rare și vă recomand să vă gândiți bine înainte de a le specifica într-o constrângere referențială. dacă ștergeți accidental o înregistrare din tabelul de referință, acest lucru poate duce la probleme mari și poate crea o reacție în lanț.

Să restabilim departamentul 3:

Acordați permisiunea de a adăuga/modifica valorile IDENTITY ​​SET IDENTITY_INSERT Departamente ON INSERT Departments(ID,Name) VALUES(3,N"IT") -- refuza adăugarea/modificarea IDENTITY values ​​​​SET IDENTITY_INSERT Departments OFF
Ștergeți complet tabelul de angajați folosind comanda TRUNCATE TABLE:

TRUNCATE TABLE Angajații
Și din nou, reîncărcați datele în ele folosind comanda anterioară INSERT:

INSERT Angajații (ID, Nume, Zi de naștere, ID Poziție, ID Departament, ID Manager) VALORI (1000,N"Ivanov II","19550219",2,1,NULL), (1001,N"Petrov P.P." ,"19831203",3 ,3,1003), (1002,N"Sidorov S.S.","19760607",1,2,1000), (1003,N"Andreev A.A.","19820417" ,4,3,1000)

Să rezumam

În acest moment, au fost adăugate câteva comenzi DDL la cunoștințele noastre:
  • Adăugarea proprietății IDENTITATE în câmp - vă permite să completați automat acest câmp (contor câmp) pentru tabel;
  • ALTER TABLE nume_tabel ADĂUGA list_of_fields_with_characteristics – vă permite să adăugați noi câmpuri la tabel;
  • ALTER TABLE nume_tabel COLOCARE COLONA list_of_fields - vă permite să eliminați câmpuri din tabel;
  • ALTER TABLE nume_tabel ADĂUGAȚI CONSTRINGERE nume_constrângere CHEIE EXTERNĂ(câmpuri) REFERINȚE lookup_table(fields) – vă permite să definiți o relație între un tabel și un tabel de căutare.

Alte restricții - UNIQUE, DEFAULT, VERIFICARE

Cu constrângerea UNIQUE, puteți spune că valoarea pentru fiecare rând dintr-un anumit câmp sau set de câmpuri trebuie să fie unică. În cazul tabelului Angajați, putem impune o astfel de restricție în câmpul Email. Doar pre-populați e-mailul cu valori dacă acestea nu sunt deja definite:

UPDATE Angajații SET Email=" [email protected]„WHERE ID=1000 UPDATE Angajații SET Email=" [email protected]" WHERE ID=1001 UPDATE Angajații SET Email=" [email protected]„WHERE ID=1002 UPDATE Angajații SET Email=" [email protected]" WHERE ID=1003
Și acum puteți impune o restricție unică pe acest câmp:

ALTER TABLE Angajații ADD CONSTRAINT UQ_Employees_Email UNIQUE(E-mail)
Acum utilizatorul nu va putea introduce același e-mail pentru mai mulți angajați.

Constrângerea de unicitate este de obicei denumită după cum urmează - mai întâi apare prefixul „UQ_”, apoi numele tabelului, iar după liniuță este numele câmpului pe care se aplică această constrângere.

În consecință, dacă o combinație de câmpuri ar trebui să fie unică în contextul rândurilor tabelului, atunci le enumerăm separate prin virgule:

ALTER TABLE nume_tabel ADD CONSTRAINT nume_constrângere UNIQUE(câmp1, câmp2,...)
Adăugând o constrângere DEFAULT unui câmp, putem seta o valoare implicită care va fi înlocuită dacă câmpul nu este listat în lista de câmpuri de comandă INSERT atunci când este inserată o nouă înregistrare. Această restricție poate fi setată direct la crearea unui tabel.

Să adăugăm un câmp nou „Data recrutării” la tabelul Angajați și să-i denumim HireDate și să spunem că valoarea implicită pentru acest câmp va fi data curentă:

ALTER TABLE Angajații ADD HireDate data NOT NULL DEFAULT SYSDATETIME()
Sau dacă coloana HireDate există deja, atunci se poate folosi următoarea sintaxă:

ALTER TABLE Angajații ADĂUGAȚI IMPLICIT SYSDATETIME() PENTRU HireDate
Aici nu am precizat numele constrângerii, deoarece în cazul DEFAULT, am fost de părere că acest lucru nu este atât de critic. Dar dacă o faci într-un mod bun, atunci, cred, nu trebuie să fii leneș și ar trebui să setezi un nume normal. Acest lucru se face după cum urmează:

ALTER TABLE Angajații ADD CONSTRAINT DF_Employees_HireDate DEFAULT SYSDATETIME() FOR HireDate
Deoarece această coloană nu exista înainte, atunci când este adăugată la fiecare înregistrare, valoarea datei curente va fi inserată în câmpul HireDate.

La adăugarea unei noi intrări, data curentă va fi de asemenea inserată automat, desigur, dacă nu o setăm în mod explicit, adică. nespecificate în lista de coloane. Să arătăm acest lucru cu un exemplu fără a specifica câmpul HireDate din lista de valori adăugate:

INSERT Angajații(ID,Nume,E-mail)VALUES(1004,N"Sergeev S.S."," [email protected]")
Să vedem ce s-a întâmplat:

SELECTAȚI * FROM Angajați

ID Nume Zi de nastere E-mail ID poziție ID departament ID manager Data angajării
1000 Ivanov I.I. 1955-02-19 [email protected] 2 1 NUL 2015-04-08
1001 Petrov P.P. 1983-12-03 [email protected] 3 4 1003 2015-04-08
1002 Sidorov S.S. 1976-06-07 [email protected] 1 2 1000 2015-04-08
1003 Andreev A.A. 1982-04-17 [email protected] 4 3 1000 2015-04-08
1004 Sergheev S.S. NUL [email protected] NUL NUL NUL 2015-04-08

Constrângerea de verificare CHECK este utilizată atunci când este necesară verificarea valorilor introduse în câmp. De exemplu, să impunem această restricție în câmpul numărului de personal, care este identificatorul nostru de angajat (ID). Folosind această constrângere, să presupunem că numerele de personal trebuie să aibă o valoare de la 1000 la 1999:

ALTER TABLE Angajații ADD CONSTRAINT CK_Employees_ID VERIFICARE (ID ÎNTRE 1000 ȘI 1999)
Constrângerea este de obicei numită la fel, mai întâi cu prefixul „CK_”, apoi numele tabelului și numele câmpului pe care se aplică constrângerea.

Să încercăm să introducem o intrare nevalidă pentru a verifica dacă restricția funcționează (ar trebui să obținem eroarea corespunzătoare):

INSERT Angajații(ID,E-mail) VALUES(2000," [email protected]")
Acum să schimbăm valoarea de inserat la 1500 și să ne asigurăm că înregistrarea este inserată:

INSERT Angajații(ID,E-mail) VALUES(1500," [email protected]")
De asemenea, puteți crea constrângeri UNIQUE și CHECK fără a specifica un nume:

ALTER TABLE Angajații ADD UNIQUE(E-mail) ALTER TABLE Angajații ADD CHECK(ID ÎNTRE 1000 ȘI 1999)
Dar aceasta nu este o practică bună și este mai bine să specificați în mod explicit numele constrângerii, deoarece pentru a vă da seama mai târziu ce va fi mai dificil, va trebui să deschideți obiectul și să vedeți de ce este responsabil.

Cu un nume bun, multe informații despre o constrângere pot fi învățate direct din numele acesteia.

Și, în consecință, toate aceste restricții pot fi create imediat la crearea unui tabel, dacă acesta nu există deja. Să ștergem tabelul:

DROP TABLE Angajații
Și recreați-l cu toate constrângerile create cu o singură comandă CREATE TABLE:

CREATE TABLE Employees(ID int NOT NULL, Nume nvarchar(30), Data zilei de naștere, Email nvarchar(30), PositionID int, DepartmentID int, HireDate date NOT NULL DEFAULT SYSDATETIME(), -- pentru DEFAULT voi arunca un CONSTRAINT PK_Employees PRIMARY EXCEPȚIE DE CHEIE (ID), CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(DepartmentID) REFERINȚE Departamente(ID), CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositionID) REFERINȚE Poziții(ID), CONSTRAINT UQ_Employees_Employees_Email_Email), UNCONSTRAINT CHEIE CHEIE_Email)

INSERT Angajații (ID, Nume, Zi de naștere, E-mail, ID Poziție, ID Departament) VALORI (1000,N"Ivanov I.I.","19550219"," [email protected]",2,1), (1001,N"Petrov P.P.","19831203"," [email protected]",3,3), (1002,N"Sidorov S.S.","19760607"," [email protected]",1,2), (1003,N"Andreev A.A.","19820417"," [email protected]",4,3)

Câteva informații despre indecșii creați la crearea constrângerilor PRIMARY KEY și UNIQUE

După cum puteți vedea în captura de ecran de mai sus, la crearea constrângerilor PRIMARY KEY și UNIQUE, au fost creați automat indici cu aceleași nume (PK_Employees și UQ_Employees_Email). În mod implicit, indexul pentru cheia primară este creat ca CLUSTERED, iar pentru toți ceilalți indecși ca NONCLUSTERED. Merită spus că conceptul de index cluster nu este disponibil în toate SGBD. Un tabel poate avea un singur index CLUSTERED. CLUSTERED - înseamnă că înregistrările tabelului vor fi sortate după acest index, se mai poate spune că acest index are acces direct la toate datele tabelului. Este, ca să spunem așa, indexul principal al tabelului. Ca să spun și mai aspru, este un index înșurubat pe masă. Indexul grupat este un instrument foarte puternic care poate ajuta la optimizarea interogărilor, țineți cont de acest lucru. Dacă vrem să spunem că indexul clusterizat nu este folosit în cheia primară, ci pentru un alt index, atunci când creăm cheia primară, trebuie să specificăm opțiunea NONCLUSTERED:

ALTER TABLE nume_tabel ADD CONSTRAINT nume_constrângere PRIMARY KEY NONCLUSTERED(câmp1, câmp2,...)
De exemplu, să facem ca indicele de constrângere PK_Employees să nu fie în cluster, iar indicele de constrângere UQ_Employees_Email să fie grupat. În primul rând, să eliminăm aceste restricții:

ALTER TABLE Angajații DROP CONSTRAINT PK_Angajați ALTER TABLE Angajații DROP CONSTRAINT UQ_Employees_Email
Și acum să le creăm cu opțiunile CLUSTERED și NONCLUSTERED:

ALTER TABLE Angajații ADD CONSTRAINT PK_Employees CHEIE PRIMARĂ NONCLUSTERED (ID) ALTER TABLE Angajații ADD CONSTRAINT UQ_Employees_Email UNIQUE CLUSTERED (E-mail)
Acum, când selectăm din tabelul de angajați, putem vedea că înregistrările sunt sortate după indexul grupat UQ_Employees_Email:

SELECTAȚI * FROM Angajați

ID Nume Zi de nastere E-mail ID poziție ID departament Data angajării
1003 Andreev A.A. 1982-04-17 [email protected] 4 3 2015-04-08
1000 Ivanov I.I. 1955-02-19 [email protected] 2 1 2015-04-08
1001 Petrov P.P. 1983-12-03 [email protected] 3 3 2015-04-08
1002 Sidorov S.S. 1976-06-07 [email protected] 1 2 2015-04-08

Înainte de aceasta, când indexul grupat era indexul PK_Employees, înregistrările erau sortate implicit după câmpul ID.

Dar în acest caz, acesta este doar un exemplu care arată esența indexului grupat, deoarece. cel mai probabil, interogările vor fi făcute către tabelul Angajați prin câmpul ID și, în unele cazuri, poate acționa în sine ca referință.

Pentru directoare, este de obicei recomandabil ca indexul grupat să fie construit pe cheia primară, deoarece în cereri, ne referim adesea la identificatorul directorului pentru a obține, de exemplu, numele (Posiție, Departament). Aici ne amintim despre ce am scris mai sus, că indexul grupat are acces direct la rândurile tabelului și de aici rezultă că putem obține valoarea oricărei coloane fără suprasarcină suplimentară.

Indexul grupat este benefic pentru a fi aplicat câmpurilor care sunt selectate cel mai des.

Uneori, tabelele creează o cheie după un câmp surogat, caz în care este util să păstrați opțiunea index CLUSTERED pentru un index mai adecvat și să specificați opțiunea NONCLUSTERED atunci când creați o cheie primară surogat.

Să rezumam

În această etapă, ne-am familiarizat cu toate tipurile de restricții, în forma lor cea mai simplă, care sunt create printr-o comandă precum „ALTER TABLE table_name ADD CONSTRAINT constraint_name ...”:
  • CHEIA PRINCIPALA- cheia principala;
  • CHEIE EXTERNĂ- stabilirea legaturilor si monitorizarea integritatii referentiale a datelor;
  • UNIC- vă permite să creați unicitate;
  • VERIFICA- vă permite să efectuați corectitudinea datelor introduse;
  • MOD IMPLICIT– vă permite să setați valoarea implicită;
  • De asemenea, merită remarcat faptul că toate restricțiile pot fi eliminate folosind comanda " ALTER TABLE nume_tabel CONSTRINGERE DE CĂDERARE nume_constrângere”.
De asemenea, am atins parțial subiectul indicilor și am analizat conceptul de cluster ( CLUSTRATE) și non-cluster ( NEGRUPAT) index.

Crearea de indici autonomi

Autosuficiența se referă aici la indecșii care nu sunt creați pentru o constrângere PRIMARY KEY sau UNIQUE.

Indecșii unui câmp sau câmpuri pot fi creați cu următoarea comandă:

CREATE INDEX IDX_Employees_Name ON Angajati(Nume)
De asemenea, puteți specifica aici opțiunile CLUSTERED, NONCLUSTERED, UNIQUE și, de asemenea, puteți specifica direcția de sortare pentru fiecare câmp individual ASC (implicit) sau DESC:

CREAȚI INDEX UNIC NECLUSTERED UQ_Employees_EmailDesc ON Angajații (E-mail DESC)
La crearea unui index non-clustered, opțiunea NONCLUSTERED poate fi omisă, așa cum este implicit implicit, este afișat aici pur și simplu pentru a indica poziția opțiunii CLUSTERED sau NONCLUSTERED în comandă.

Puteți elimina indexul cu următoarea comandă:

DROP INDEX IDX_Employees_Name ON Angajații
Indecșii simpli, la fel ca și constrângerile, pot fi creați în contextul comenzii CREATE TABLE.

De exemplu, să ștergem din nou tabelul:

DROP TABLE Angajații
Și recreați-l cu toate constrângerile și indecșii creați cu o singură comandă CREATE TABLE:

CREATE TABLE Angajații(ID int NOT NULL, Nume nvarchar(30), Data zilei de naștere, Email nvarchar(30), PositionID int, DepartmentID int, HireDate date NOT NULL CONSTRAINT DF_Employees_HireDate DEFAULT SYSDATETIME(), ManagerID int, CONSTRAINT PK_Employees PRIMARY (PRIMARY) ), CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(DepartmentID) REFERINȚE Departamente(ID), CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositionID) REFERINȚE Poziții(ID), CONSTRAINT FK_Employees_ManagerID FOREIGN KEY(ID)Employees_ManagerID (ID STRĂINĂ) CONSTRAINTE CONSTRAINT_0Employees_CONSEmail0 CONSTRAINT 1999), INDEX IDX_Employees_Name(Nume))
În cele din urmă, introduceți în tabelul angajaților noștri:

INSERT Angajații (ID, Nume, Zi de naștere, E-mail, ID Poziție, ID Departament, ID Manager) VALORI (1000,N"Ivanov II","19550219"," [email protected]",2,1,NULL), (1001,N"Petrov P.P.","19831203"," [email protected]",3,3,1003), (1002,N"Sidorov S.S.","19760607"," [email protected]",1,2,1000), (1003,N"Andreev A.A.","19820417"," [email protected]",4,3,1000)
În plus, este de remarcat faptul că valorile pot fi incluse într-un index non-cluster, specificându-le în INCLUDE. Acestea. în acest caz, indicele INCLUDE va ​​semăna oarecum cu un index grupat, doar că acum indicele nu este atașat tabelului, dar valorile necesare sunt atașate indexului. În consecință, astfel de indecși pot îmbunătăți considerabil performanța interogărilor selectate (SELECT), dacă toate câmpurile enumerate sunt în index, atunci este posibil să nu fie deloc nevoie să accesați tabelul. Dar acest lucru crește în mod natural dimensiunea indicelui, deoarece valorile câmpurilor enumerate sunt duplicate în index.

Decuparea din MSDN. Sintaxă generală de comandă pentru crearea de indexuri

CREATE [UNIQUE] [CLUSTER | NONCLUSTERED ] INDEX nume_index ACTIVAT (coloana [ ASC | DESC ] [ ,...n ]) [ INCLUDE (nume_coloană [ ,...n ]) ]

Să rezumam

Indecșii pot crește viteza de regăsire a datelor (SELECT), dar indecșii reduc viteza de actualizare a datelor din tabel, deoarece după fiecare modificare, sistemul va trebui să reconstruiască toți indecșii pentru un anumit tabel.

Este de dorit în fiecare caz să se găsească soluția optimă, media de aur, astfel încât atât performanța de eșantionare, cât și modificarea datelor să fie la nivelul corespunzător. Strategia de creare a indicilor și numărul acestora pot depinde de mulți factori, cum ar fi cât de des se schimbă datele din tabel.

Concluzie despre DDL

După cum puteți vedea, limbajul DDL nu este atât de complicat pe cât ar părea la prima vedere. Aici am putut arăta aproape toate desenele sale principale, folosind doar trei tabele.

Principalul lucru este să înțelegeți esența, iar restul este o chestiune de practică.

Mult succes în stăpânirea acestui limbaj minunat numit SQL.

  • Serghei Savenkov

    un fel de recenzie „puțin”... parcă s-ar grăbi undeva