Vienkāršs SQL Insert teikums

Pārējos rakstus var lasīt SQL pamatos.

Vienkāršam Insert teikumam ir divi veidi. Ja izmanto VALUES klauzu, tad tiek pievienota tieši viena rinda (pieņemot, ka pievienošana noritēja bez kļūdām), savukārt izmantojot apakšvaicājumu, tiek pievienoti tik ieraksti, cik apakšvaicājums atgriež, tātad iespējams neviens, viens vai daudzi.

Insert teikums ar VALUES klauzu

Sintakse šim SQL teikumam ir šāda:

INSERT INTO <tabula un kolonas>
VALUES <vērtības>

INSERT INTO ir atslēgvārdi, bez kuriem nevar iztikt. Tālak tiek rakstīts tabulas nosaukums, kurā tiks pievienots ieraksts. Pēc tabulas nosaukuma var neobligāti uzskaitīt kolonas, kurās tiks pievienotas vērtības. Ja kolonu uzskaitījums netiek dots, tādā gadījumā VALUES klauzā ir jānorāda visas vērtības tādā skaitā, cik ir kolonas tabulā un vērtības tiek liktas tabulā skatoties pēc kolonu pozicionālā novietojuma.
Piemēriem izmantosim tabulas, kas definētas ierakstā par dekarta reizinājumu.

Piemērs 1. INSERT teikums ar VALUES klauzu bez kolonu uzskaitījuma.
SQL> INSERT INTO adreses
  2  VALUES (1, 'RĪGA', 'BRĪVĪBAS IELA 123, dz. 456');
1 row created.

Piemērs 2. INSERT teikums ar VALUES klauzu bez kolonu uzskaitījuma – ja vērtību skaits nesakrīt ar tabulas kolonu skaitu ir kļūda.
SQL> INSERT INTO adreses VALUES (2, 'LIELĀ IELA 12, dz. 34');
INSERT INTO adreses VALUES (2, 'LIELĀ IELA 12, dz. 34')
*
ERROR at line 1:
ORA-00947: not enough values

Var izvairīties no šādām kļūdām un tai kolonai, kurai vērtību negribam pievienot, norādīt atslēgas vārdu DEFAULT. Tas gan nestrādās visās DBVS.

Piemērs 3. INSERT teikums ar VALUES klauzu bez kolonu uzskaitījuma ar DEFAULT atslēgas vārdu.
SQL> INSERT INTO adreses VALUES (2, DEFAULT,'LIELĀ IELA 12, dz. 34');
1 row created.

Otrs veids, kā izvairīties no šādām kļūdām, ir vienkārši uzskaitīt kolonas, kurās ievietot vērtības. Šādā gadījumā jāatceras vairākas lietas:

  • kolonu skaitam un vērtību skaitam ir jāsakrīt;
  • vērtības tiks ievietotas tādā kārtībā kā pozicionāli uzskaitītas kolonas;
  • tām kolonām, kas nav uzskaitījumā, tabulā tiks ieliktas to noklusētās vērtības. Ja tāda netika specificēta, tad noklusētā vērtība parasti ir NULL;
  • ja nav norādīta vērtība kolonai, kam ir NOT NULL ierobežojums un nav noklusētā vērtība, tad jūs iegūsiet kļūdu, ja vien nebūs kādi ļoti speciāli nosacījumi, piemēram, trigeris uz tabulu, kas aizpilda šādas kolonas.

Piemērs 4. INSERT teikums ar VALUES klauzu ar kolonu uzskaitījumu.
SQL> INSERT INTO adreses (
  2     adr_id
  3    ,adr_teksts
  4  ) VALUES (
  5     3
  6    ,'CĒSU IELA 1, dz. 2');
1 row created.

Piemērs 5. INSERT teikums, kurā nav norādīta obligātā kolona.
SQL> INSERT INTO adreses (adr_id) VALUES (4);
INSERT INTO adreses (adr_id) VALUES (4)
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("GINTS"."ADRESES"."ADR_TEKSTS")

Protams fiksētu vērtību vietā var lietot funkcijas un izteiksmes, kas katrā DBVS var būt savādākas. Piemēram pievienojam adreses tabulai divas kolonas, kurās likt ieraksta ievietošanas laika nospiedumu (current_timestamp) un pašreizējo lietotāju (user).

SQL> ALTER TABLE adreses ADD (
  2    adr_pievienosanas_datums TIMESTAMP,
  3    adr_lietotajs VARCHAR2(30));
Table altered.

Piemērs 6. INSERT teikums, ar iebūvētajām funkcijām.
SQL> INSERT INTO adreses VALUES (
  2    5, 'JELGAVA', 'RĪGAS IELA 1, dz. 3',
  3    current_timestamp, user);
1 row created.

Insert teikums ar apakšvaicājumu

Sintakse šim SQL teikumam ir šāda:

INSERT INTO <tabula un kolonas>
SELECT <select teikums>

Tātad INSERT INTO klauza ir tāda pati kā augstāk minētajā gadījumā – ir jānorāda tabulas vārds, kurā ieraksti tiks pievienoti, bet kolonas var norādīt un var arī nenorādīt. Savukārt otrā daļa ir kardināli atšķirīga – šeit parasti netiek norādītas specifiskas vērtības, bet ņemtas esošo datu kolonu vērtības un tās pievienotas norādītajai tabulai. Pie tam šis SELECT teikums var būt pēc patikas sarežģīts un atlasīt datus no daudzām tabulām izmantojot savienojumus un jebkādas citas konstrukcijas, kas tiek atļautas SELECT teikumā. Tātad ir vairākas lietas ko ir vērts šeit atcerēties:

  • Ja vien tas iespējams, tad rakstiet Insert teikumu ar apakšvaicājumu, nevis ciklā ejiet cauri Select vaicājuma rezultātam un tad katram ierakstam izpildiet Insert ar Values klauzu. Vispārīgā gadījumā tas ir saprotamāk, jo prasa mazāk kodu, ātrāk, jo datubāze var izmantot iebūvētās optimizēšanas metodes un pievienot ierakstus kā kopu.
  • Dažkārt var šķist, ka Insert ar apakšvaicājums strādā krietni ilgāk nekā vienkāršs Select pieprasījums, kas kaut kādus datus atlasa uz ekrāna. Pirmkārt, tas ir objektīvu iemeslu dēļ, jo, pievienojot ierakstus, ir jāveic to pievienošana gana tabulā, gan iespējams jāuztur indeksi un jāveic vēl citas operācijas, ja uz tabulas, piemēram, ir definēti trigeri. Taču visbiežāk bremze ir šķietama, jo ļoti daudzi GUI (graphical user interface, grafiskā lietotāja saskarne t.i. lietotājam draudzīgie SQL rīki) attēlo tikai pirmos N atlasītos ierakstus un lietotājs nemaz neveic šo datu pilnu atlasi un nepārliecinās, ka VISU pieprasīto datu atlase aizņem daudz vairāk laika, nekā pirmo N rindiņu atlase. Tas pats attiecas arī uz potenciālu ierakstu skaita noskaidrošanu (SELECT COUNT(*) FROM ()) – datubāze, var iekšēji veikt optimizācijas un, lai noskaidrotu ierakstu skaitu, tai iespējams nav jāveic pilns SELECT teikums, kas būtu jāveic, ja tiktu atlasīti visi dati.

Tātad izveidojam otru tabulu, papildus jau esošai adrešu tabulai:

SQL> CREATE TABLE adr_kopija (
  2     adr_id NUMBER NOT NULL
  3    ,adr_pilseta VARCHAR2(40)
  4    ,adr_teksts VARCHAR2(40) NOT NULL
  5    ,adr_pievienosanas_datums TIMESTAMP
  6    ,adr_lietotajs VARCHAR2(30));
Table created.

Piemērs 7. INSERT teikums ar apakšvaicājumu
SQL> INSERT INTO adr_kopija
  2  SELECT * FROM adreses
  3  WHERE adr_id <=2;
2 rows created.

Piemērs 8. INSERT teikums ar apakšvaicājumu, atlasot tikai daļu kolonu un dažas aizstājot ar funkcijām
SQL> INSERT INTO adr_kopija
  2  SELECT adr_id, adr_pilseta, adr_teksts,
  3         current_timestamp, user
  4  FROM adreses
  5  WHERE adr_pievienosanas_datums IS NOT NULL;
1 row created.

Paskatamies kāds rezultāts mums ir sanācis abiem šiem ierakstiem:

SQL> SELECT orig.adr_id,
  2    orig.adr_pievienosanas_datums,
  3    kopija.adr_pievienosanas_datums,
  4    orig.adr_pilseta,
  5    kopija.adr_pilseta,
  6    orig.adr_teksts,
  7    kopija.adr_teksts
  8  FROM adreses orig INNER JOIN adr_kopija kopija
  9  ON orig.adr_id = kopija.adr_id
 10  AND orig.adr_pievienosanas_datums IS NOT NULL;

    ADR_ID ADR_PIEVIENOSANAS_DATUMS      ADR_PIEVIENOSANAS_DATUMS
---------- ----------------------------  ---------------------------
ADR_PILSETA                              ADR_PILSETA
---------------------------------------- ---------------------------
ADR_TEKSTS                               ADR_TEKSTS
---------------------------------------- ---------------------------
         5 2008.05.10 00:29:02,111000    2008.05.10 01:22:54,033000
JELGAVA                                  JELGAVA
RĪGAS IELA 1, dz. 3                      RĪGAS IELA 1, dz. 3

Tātad kā redzam, oriģinālājā ierakstā un kopijas ierakstā pilsētas un teksta lauku sakrīt, bet pievienošanas laikspiedols ne.

Kopsavilkums

Augstākminētie INSERT teikumu sintakses veidi nebūt nav vienīgie un izsmeļošie. Taču ar tiem pamatā pietiek, lai varētu veikt datu pievienošanu gan fiksētām vērtībām vienam ierakstam, gan datu kopēšanu no jau esošām citām tabulām. Pie tam šeit uzskaitītie veidi, ja neskaita funkcijas, tad citādi darbojas pārsvarā visās DBVS. Nākošajā rakstā paskatīsiemies arī uz dažādiem eksotiskākiem ierakstu pievienošanas veidiem, kas gan lielākoties būs specifiski tikai kādām konkrētām DBVS.

Tālākā lasāmviela

Komentēt

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Mainīt )

Twitter picture

You are commenting using your Twitter account. Log Out / Mainīt )

Facebook photo

You are commenting using your Facebook account. Log Out / Mainīt )

Google+ photo

You are commenting using your Google+ account. Log Out / Mainīt )

Connecting to %s

%d bloggers like this: