Składnia polecenia INSERT jest mniej więcej następująca: INSERT [PARAMETRY] tabela VALUES [OPCJE]] Listing 1.0 obrazuje tą strukturę dokładniej, w trzech możliwych formach.
Polecenie INSERT dodaje wiersz danych złożony z jednej lub kilku wartości dla podanych kolumn w odpowiedniej tabeli.
Składnia INSERT ... VALUES oraz INSERT ... SET wstawiają nowe rekordy jeśli dokładnie podamy wszystkie wartości (do wszystkich pól tablic). Składnia INSERT ... SELECT wstawia rekordy wybrane z innej tablicy lub z innych tablic.
Nazwy kolumn, do których będziemy definiować dane można zadać dokładnie albo podając w poleceniu INSERT listę nazw kolumn (kol1,kol2,...) albo stosując drugą z wymienionych składnię , a więc używając słowa SET. Jeśli nie chcemy podawać nazw kolumn (bo na przykład może być ich dużo) to nie musimy tego robić; wystarczy jeśli podamy poprawnie listę wartości, ale bezwględnie ważna jest tutaj kolejność wartości na liście wartości VALUES(). Jeśli nie znamy struktury tablicy albo kolejności pól (kolumn) to możemy posłużyć się poleceniem DESCRIBE nazwa_tablicy.
Wartości kolumn możemy podawać na kilka różnych sposobów:
-
jeśli nie podamy wartości dla kolumny to przyjmowana jest wartość domyślna, zdefiniowana podczas definicji struktury tablicy. Możemy na przykład nie podać wartości wszystkich pól (kolumn) tablicy. W takim przypadku MySQL wypełni wartościami domyślnymi wszystkie pola wstawianego rekordu. MySQL ma zawsze zdefiniowane wartości dla wszystkich kolumn. Nienadawanie wartości polom rekordu nie jest jednak dobrym nawykiem, gdyż z bazy danych korzystają aplikacje, które najczęściej oczekują konkretnych danych, a nie wartości domyślnych. Przykład na Listingu 2.0
-
Począwszy od wersji 4.0.3 MyQL-a można użyć słowa DEFAULT aby dosłownie nadać wartość domyślną polu rekordu.(patrz Listing 3.0)
-
Jeśli typ danych, które chcemy wstawić do tablicy nie odpowiada typowi kolumny zadeklarowanemu podczas tworzenia tablicy, wtedy może nastąpić domyślna konwersja do odpowiedniego typu danych. Na przykład próba wstawienia stringu '1999.0e-2' do kolumn typu INT, FLOAT, DECIMAL(10,6) lub YEAR spowoduje wstawienie odpowiednio 1999, 19.9921, 19.992100, i 1999. Powodem, dla którego w kolumnach typu INT i YEAR znajdzie się 1999 jest to, że funkcja dokonująca konwersji typu string-to-integer "patrzy" tylko na początek stringu '1999.0e-2' i "widzi", że pasuje do formatu liczby całkowutej albo roku. W przypadku kolumn typu zmiennoprzecnikowego lub stałoprzecinkowego funkcja dokonująca konwersji typu string-to-floating-point i string-to-fixed-point "patrzy" na cały string jak na potencjalną liczbę o właściwej konsrukcji.
-
Wyrażenie wyr może się odnosić do dowolnej kolumny, dla której wartość zdefiniowano wcześniej (w tej samej instrukcji INSERT).(patrz Listing 4.0 w 2 przkładach)
Przykład 1:
Tutaj można się było odwołać do col1, gdyż col1 było zdeiniowane wcześniej niż col2.
Przykład 2:
To wyrażenie jest niepoprawne, gdyż wartość col1 odnosi się do col2, która nie została jeszcze zdefiniowana.
Można stosować następujące parametry wywołania polecenia INSERT:
-
Parametr DELAYED powoduje wstawienie wiersza lub wierszy do buforu. Dane z fubora są wstawiane do tablicy w momencie, kiedy jest ona "wolna", tzn. nie ma do niej w danej chwili żadnych zapytań. Sprawdzanie jest dokonywane cyklicznie. Jeśli w wyniku któregoś sprawdzenia okaże się, że są zapytania do danej tablicy, wtedy polecenie INSERT jest wstrzymywane do momentu aż nie nastąpi "zwolnienie" tablicy.
-
Parametr LOW_PRIORITY powoduje opóźninie wykonania polecenia INSERT doputy, dopóki klienci czytają dane z danej tablicy. Może to spowodować długie czekanie na wykonanie INSERT LOW_PRIORITY, w przypadku kiedy baza jest mocno obciążona zapytaniami do tablicy. W przeciwieństwie do opcji LOW_PRIORITY opcja DELAYED pozwala klientowi kontynuować natychmiast, kiedy tylko zwolni się dostęp do tablicy.
-
Parametr HIGH_PRIORITY powoduje zaniechanie konsekwencji jakie pociąga ze sobą uruchomienie bazy danych z opcją --low-priority-updates. Baza danych uruchomiona z taką opcją domyślnie pozwala wykonywać polecenia zmiany danych w tablicach (polecenia INSERT, UPDATE tak, jakby były one wykonywane z opcją LOW_PRIORITY.
-
Parametr IGNORE powoduje ignorowanie wstawianych rekordów jeśli zawierają istniejący już w wierszu/ach tablicy indeks UNIQUE lub PRIMARY KEY. Jeśli uruchomimy polecenie INSERT bez tego parametru i znajdzie się wiersz, który duplikuje istniejący klucz UNIQUE lub PRIMARY KEY wtedy całe polecenie wstawiające kilka wierszy jest przerywane. Jest to dość kłopotliwa sytuacja gdyż wtedy najczęściej trzeba zliczyć w jakiś sposób ile rekordów zostało do bazy wstawionych, i które rekordy zostały wstawione.
Jeśli do polecenia INSERT dopiszemy ON DUPLICATE KEY UPDATE wtedy zamiast przerywania wykonania całego polecenia INSERT lub omijania takich rekordów, które duplikują wartość indeksu UNIQUE lub PRIMARY KEY, następuje UPDATE rekordu.
Na przykład jeśli kolumna a jest zadeklarowana jako UNIQUE i już zawiera wartość 1, to poniższe dwa wyrażenia dają ten sam efekt:(patrz Listing 5.0)
Uwaga. Jeśli kolumna b również jest zadeklarowana jako UNIQUE wtedy polecenie INSERT może być równoważne następującemu poleceniu UPDATE:(patrz Listing 6.0)
Jeśli a=1 OR b=2 pasuje do kilku (kilkunastu) wierszy wtedy trzeba pamiętać, że tylko jeden wiersz jest zmieniany instrukcją UPDATE. Lepiej więc zabezpieczać się przed takimi wypadkami definiując odpowiednio tablice używając klauzuli ON DUPLICATE KEY niż wierzyć że jeśli się coś stanie to ON DUPLICATE KEY UPDATE uratuje nas przecież.
Od wersji 4.1.1 MySQLa można używać funkcji VALUES(col) w klauzuli ON DUPLICATE KEY UPDATE odnosząc się do kolumn z części INSERT ... UPDATE. Innymi słowy VALUES(col) w klauzuli ON DUPLICATE KEY UPDATE odnosi się do wartości kolumny col, która mogłaby zostać wstawiona jeśli nie zdarzyłby się konflikt duplikacji klucza. Jest to szczególnie użyteczne, kiedy wstawiamy dane do wielu wierszy za pomoca jednego polecenia INSERT.
Na przykład patrz Listing 7.0
Takie wyrażenie jest równoważne następującym dwom wyrażeniom (patrz Listing 8.0).
Jeśli używamy opcji ON DUPLICATE KEY UPDATE wtedy automatycznie parametr DELAYED jest ignorowany.
W przypadku kolumn zadeklarowanych jako AUTO_INCREMENT można dowiedzieć się, jaka była ostatnia wartość takiej kolumny posługując się funkcją LAST_INSERT_ID().
Jeśli posługujemy się wrażeniem INSERT ... VALUES z wieloma listami wartości, albo kiedy posługujemy się wyrażeniem postaci INSERT ... SELECT wtedy baza zwróci nam informację mniej więcej następującej postaci:
Records: 100 Duplicates: 0 Warnings: 0
Records wskazuje na liczbę analizowanych rekordół (to niekoniecznie musi być liczba wstawionych rekordów). Duplicates wskazuje na liczbę rekordów, które nie mogły być wstawione ze względu na duplikację wartości unikalnych. Warnings wskazuje na liczbę prób wstawienia wartości do kolumn, które z jakichś powodów były problematyczne. Warnings mogą się zdarzyć w następujących przypadkach:
-
Kiedy chcemy wstawić wartość NULL do kolumny, która była zadeklarowana jako NOT NULL. W przypadku polecenia INSERT wielowierszowego lub polecenia INSERT ... SELECT wartość dla tej kolumny jest ustawiana na podstawie wartości domyślnej dla tej kolumny, a zatem 0 dla typów numerycznych, pusty string '' dla typów znakowych, oraz ``zero'' dla kolumn typu data i czas.
-
Kiedy chcemy wstawić wartość, która przekracza dopusczalny zakres wartości dla danej kolumny. Następuje wtedy obcięcie do najbliższej z możliwych wartości. Dotyczy to zarówno wartości liczbowych, jak i znakowych.
-
Kiedy chcemy wstawić wartość zupełnie innego typu, niż wynika to z definicji typu kolumny, np. kiedy chcemy wstawić '10.34 a' do kolumny numerycznej. Ogn tego strinu (nienumeryczny) jest odciety i dostaje się do bazy tylko część numeryczna. Jeśli string nie miałby w sobie nic z cyfry, wtedy wstawiona by była wartość 0.
-
Kiedy chcemy wstawić wartość do kolumny typu date lub time, która jest nieodpowiednia dla tego typu kolumny. Wtenczas wartość kolumny jest ustawiana domyślnie jako odpowiednie ``zero''.
Listing
INSERT
[LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tabela [(kol1,kol2,...)]
VALUES ({wyr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE kol=wyr, ... ]
--lub:
INSERT
[LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tablica
SET kol={wyr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE kol=wyr, ... ]
--lub też
INSERT
[LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tablica [(kol1,kol2,...)]
SELECT ...
--Listing 2.0
INSERT INTO nazwa_tab () VALUES();
--Listing 3.0
INSERT INTO nazwa_tab VALUES (DEFAULT,DEFAULT,'Kowalski','18','1','0',DEFAULT);
--Listing 4.0
INSERT INTO tab (col1,col2) VALUES(15,col1*2);
INSERT INTO tab (col1,col2) VALUES(col2*2,15);
--Listing 5.0
INSERT INTO tab (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;
UPDATE tab SET c=c+1 WHERE a=1;
--Listing 6.0
UPDATE tab SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
--Listing 7.0
INSERT INTO tab (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
--Listing 8.0
INSERT INTO tab (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3;
INSERT INTO tab (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=9;
Ranga: Administrator serwisu Punktów: 0