Instrukcja DELETE
Składnia dla jednej tabeli:
Składnia dla wielu tabel:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
tabela_1 [, tabela_2 ...]
FROM lista_tabel
[WHERE warunek]
lub:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
FROM tabela_1 [, tabela_2 ...]
USING lista_tabel
[WHERE warunek]
Instrukcja DELETE usuwa wiersze spełniające warunek z podanej tabeli i zwraca ilość usuniętych wierszy.
Jeżeli użyjesz instrukcji DELETE bez klauzuli warunkowej WHERE, to z tabeli zostaną usunięte wszystkie wiersze. Jeżeli rzeczywiście
chcesz usunąć z tabeli wszystkie wiersze, to bardziej efektywną metodą jest użycie instrukcji TRUNCATE TABLE, która kasuje
istniejącą tabelę i tylko tworzy od nowa jej strukturę. Instrukcja DELETE zawsze usuwa wiersz po wierszu z tabeli.
Klauzule instrukcji delete
:
LOW_PRIORITY
powoduje, że wykonanie instrukcji zostanie odłożone do momentu, gdy żaden inny klient
nie będzie czytał danych z tabeli;
QUICK
pomija pliki indeksowe podczas usuwania, co może przyspieszyć operację; opcja może być przydatna przy usuwaniu
dużej ilości rekordów (indeksy powinny być po usunięciu odbudowane instrukcja OPTIMIZE TABLE
);
IGNORE
powoduje ignorowanie błędów, które mogą pojawić się podczas wykonywania operacji.
Opcja LIMIT ilość_wierszy
określa ile maksymalnie rekordów może zostać usuniętych z tabeli zamin sterowanie
zostanie zwrócone do klienta. Może być przydatna przy usuwaniu dużej ilości rekordów oraz w przypadku usuwania rekordów zdublowanych.
Instrukcja DELETE
z klauzulą ORDER BY
określa kolejność usuwania rekordów z tabeli. Moze być użyteczna w
połączeniu z klauzulą LIMIT
. Np.: poniższa instrukcja posortuje tabele według daty i czasy, a następnie usunie tylko
pierwszy (najstarszy) rekord:
DELETE FROM logowania
WHERE user = 'kowalski'
ORDER BY data_czas
LIMIT 1;
Możliwe jest usuwanie wierszy z wielu tabel jednocześnie. Tabele muszą być złączone warunkiem podobnym do klauzuli
JOIN
w instrukcji SELECT
. W przypadku usuwania wierszy z wielu tabel jednocześnie zabronione są
klauzule ORDER BY
i LIMIT
.
Wiersze zostaną usunięte tylko z tabel tabela_1, tabela_2,...
. Np.:
DELETE t1, t2
FROM t1, t2, t3
WHERE t1.id=t2.id AND t2.id=t3.id;
lub
DELETE FROM t1, t2
USING t1, t2, t3
WHERE t1.id=t2.id AND t2.id=t3.id;
W tym przykładzie używane są 3 tabele, ale rekordy zostaną usunięte tylko z tabel t1
i t2
.
Możliwe jest również usuwanie wierszy z połączenia tabel z różnych baz, np.:
DELETE baza_1.t1, baza_2.t2 FROM baza_1.t1, baza_2.t2 WHERE ...
Instrukcja DO
Instrukcja DO wykonuje wyrażenieN
, ale nie zwraca żadnego wyniku. Jest identyczna z instrukcją
SELECT wyrażenie1 ...
, ale działa znacznie szybciej, bo żaden wynik nie jest zwracany.
DO jest użyteczne z funkcjami typu RELEASE_LOCK(). W innych przypadkach raczej nie ma zastosowania.
Instrukcja HANDLER
Instrukcja HANDLER
umożliwia bezpośredni dostęp do danych w tabeli.
HANDLER ... OPEN
otwiera tabelę i czyni ją dostępną dla sekwencji kolejnych instrukcji HANDLER ... READ
.
Tabela jest współdzielona z innymi wątkami i klientami bazy i pozostaje otwarta aż do wystąpienia instrukcji
HANDLER ... CLOSE
lub zakończenia połączenia z bazą. Jeżeli otworzysz tabelę definiując dla niej alias,
to wszystkie następne instrukcje HANDLER
muszą odwoływać się do tabeli poprzez ten alias.
Pierwsza składnia instrukcji HANDLER ... READ
pobiera wiersz tabeli, dla którego wartość podanego indeksy spełnia
podany warunek i wartości pól rekordu spełniają warunek WHERE
(o ile go podałeś). Dla indeksów wielopolowych wartość
indeksu należy podać jako listę wartości kolejnych poł oddzielonych przecinkami. Można przy tym pominąć wartości dla ostatnich
pól indeksy, ale nie dla początkowych. Np. dla indeksu składającego się z 3 pól można podać:
HANDLER ... indeks = (kol_1_wart, kol_1_wart, kol_1_wart) ...
HANDLER ... indeks = (kol_1_wart, kol_1_wart) ...
HANDLER ... indeks = (kol_1_wart) ...
Druga składnia instrukcji HANDLER ... READ
pobiera z tabeli odpowiedni: pierwszy, następny, poprzedni lub ostatni
wiersz w kolejności indeksu i warunku WHERE
.
Ostatnia składnia instrukcji HANDLER ... READ
pobiera wiersz tabeli w naturalnym porządku (w kolejności zapisu
wierszy w tabeli z pominięciem indeksów) z uwzględnieniem jedynie warunki klauzuli WHERE
. Działa znacznie
szybciej niż poprzednie.
Bez klauzuli LIMIT
instrukcja HANDLER ... READ
zwraca pojedynczy wiersz tabeli. Jeżeli chcesz
odczytać określoną ilość wierszy, to użyj klauzuli LIMIT
. Działa identycznie, jak w instrukcji SELECT
.
HANDLER ... CLOSE
zamyka tabelę otwartą poleceniem HANDLER ... OPEN
.
HANDLER
nie blokuje tabeli. Oznacza to, że inni klienci mogą w tym samym czasie ją modyfikować, a zmiany mogą
być tylko częściowo widoczne.
Zalety instrukcji HANDLER
w stosunku do SELECT
:
HANDLER
jest znacznie szybsze od SELECT
;
HANDLER
upraszcza programowanie z poziomu aplikacji korzystającej z bazy MySQL;
HANDLER
traktuje tabelę jak zwykły plik, co może być prostsze w użyciu dla programisty tworzącego interfejs bazy danych.
Instrukcja INSERT
Polecenie INSERT
wstawia nowe wiersze do istniejącej tabeli.
Forma INSERT ... VALUES
wstawia wiersze opierając się na wartościach podanych wprost, natomiast forma
INSERT ... SELECT
wstawia wiersze pobrane z innej tabeli lub tabel.
Nazwa_tabeli
jest tabelą, do której zostaną wstawione nowe wiersze. Lista kolumn lub klauzula SET
wskazuje,
dla których kolumn podawane są wartości.
- Jeżeli nie wyszczególniono listy kolumn w poleceniu
INSERT ... VALUES
lub INSERT ... SELECT
,
w klauzuli VALUES()
lub instrukcji SELECT
należy podać wartości dla wszystkich kolumn.
Jeżeli nie znasz porządku kolumn w tabeli, możesz się tego dowiedzieć używając polecenia DESCRIBE nazwa_tabeli
.
- Jeżeli dla danej kolumny nie podano wprost wartości, zostanie ona wypełniona wartością domyślną. Na przykład,
jeżeli podano listę kolumn w tabeli nie obejmującą wszystkich pól, nie wymienione kolumny przyjmą wartości domyślne.
Taki sam efekt osiągniesz podając dla konkretnego pola słowo kluczowe
DEFAULT
.
Wyrażenie
może odwoływać się do każdej kolumny, która została wcześniej ustawiona. Na przykład, można zrobić tak:
INSERT INTO nazwa_tabeli (col1, col2) VALUES(15, col1 * 2);
ale nie wolno tak:
INSERT INTO nazwa_tabeli (col1, col2) VALUES (col2 * 2, 15);
- Jeżeli użyjesz słowa kluczowego
LOW_PRIORITY
, wykonanie polecenie INSERT
zostaje odłożone do czasu,
kiedy żaden inny klient nie będzie odczytywał danych z tabeli. W takim przypadku klient musi czekać z zakończeniem wykonywania
polecenia wstawiania wierszy, co przy bardzo obciążonej tabeli może trwać dość długo. Jest to przeciwieństwem polecenia
INSERT DELAYED
, który pozwala na natychmiastową kontynuację pracy klienta (wiersze mające zostać wstawione
ustawiane są w kolejce, po czym kontrola natychmiast wraca do klienta, dzięki czemu może one wykonywać bez opóźnień
dalsze operacje). Pamiętaj, że LOW_PRIORITY
nie powinno być używane w przypadku tabel MyISAM
,
ponieważ uniemożliwia to jednoczesne wykonywanie operacji wstawiania.
- Jeżeli użyjesz słowa kluczowego
IGNORE
w instrukcji INSERT
mającej wstawić wiele wierszy,
to każdy wiersz powielający istniejący w tabeli klucz PRIMARY
lub UNIQUE
zostaje zignorowany
i nie jest wstawiany, ale operacja wstawiania wierszy jest kontynuowana. Jeżeli pominiesz IGNORE
, to w przypadku
wykrycia duplikatu indeksu lub innego błędu operacja wstawiania zostaje przerywana.
- Jeżeli MySQL został skonfigurowany z opcją
DONT_USE_DEFAULT_FIELDS
, to w przypadku nie podania wartości
dla wszystkich kolumn wymagających wartości różnej od NULL zostanie wygenerowany błąd.
- W przypadku instrukcji
INSERT INTO ... SELECT
obowiązują następujące zasady:
- polecenie nie może zawierać klauzuli
ORDER BY
;
- tabela docelowa instrukcji
INSERT
nie może występować w klauzuli FROM
części
SELECT
, ponieważ jest to zabronione w ANSI SQL (problemem jest to, że polecenie SELECT
mogłoby wybrać rekordy wstawione wcześniej tym samym zapytaniem. Gdybyśmy jeszcze używali podzapytań
(zapytań zagnieżdżonych), sytuacja bardzo łatwo mogłaby skomplikować.
- kolumny
AUTO_INCREMENT
zachowują się normalnie.
W przypadku próby wstawienia do kolumn wartości, które z jakiś względów okazały się problematyczne podjęte zostają poniższe działania:
- wstawianie wartości NULL do kolumny zadeklarowanej jako
NOT NULL
: wstawiana jest wartość domyślna;
- wstawianie do kolumny numerycznej wartości wykraczającej poza dany typ: wstawiana jest skrajna najwyższa wartość
zadeklarowanego typu;
- wstawianie do kolumny numerycznej wartości takiej jak
'10.34 a'
: usuwane są końcowe błędne dane,
a reszta jest wstawiana do kolumny; jeżeli wartość w ogóle nie ma sensu dla danej kolumny, wstawiana jest wartość 0;
- wstawianie do kolumn typu
CHAR
, VARCHAR
, TEXT
lub BLOB
łańcuchów
przekraczających maksymalną długość typu: wstawiana dana jest obcinana do dopuszczalnego rozmiaru;
- wstawianie błędnej danej do kolumn z rodziny typów data i czas: kolumna wypełniana jest wartością "zero" odpowiednią
dla danego typu.
Opcja DELAYED
w instrukcji INSERT
jest opcją występującą tylko w MySQL. Jest ona bardzo przydatna jeżeli
klient nie może czekać na zakończenie wykonywania operacji INSERT
. Jest to powszechny problem jeżeli używasz MySQL
do logowania, a także okresowo uruchamiasz długotrwałe polecenia SELECT
. W przypadku używania
INSERT DELAYED
, klient natychmiast odzyskuje kontrolę, a wiersze zostają wstawione, kiedy tabela nie jest używana
przez żaden inny wątek.
Inną wielką zaletą INSERT DELAYED
jest to, że instrukcje INSERT
pochodzące od wielu klientów są
zbierane razem i zapisywane w jednym bloku. Jest to znacznie szybszy sposób niż robienie tego w oddzielnych operacjach.
Pamiętaj, że obecnie skolejkowane wiersze do czasu wstawienia to tabeli są przechowywane tylko w pamięci. Oznacza to,
że jeżeli twardo zamkniesz proces mysqld
lub jeżeli mysqld
zostanie zamknięty z innych
przyczyn, wszystkie wiersze które nie zdążyły zostać zapisane na dysku będą bezpowrotnie utracone.
Jeżeli podasz klauzulę ON DUPLICATE KEY UPDATE
, a wstawiany wiersz posiada istniejąca juz wartość dla indeksu
zadeklarowanego jako UNIQUE
lub PRIMARY KEY
, to zamiast wstawienia nowego wiersza wykonywana jest
instrukcja UPDATE
dla wiersza już istniejącego. Np.: jeżeli kolumna a jest zadeklarowana jako
UNIQUE
i istnieje już wartość 1, to obie poniższe instrukcje dadzą ten sam efekt:
mysql> INSERT INTO tabela (a, b, c) VALUES (1, 2, 3)
-> ON DUPLICATE KEY UPDATE c=c+1;
mysql> UPDATE tabela SET c = c + 1 WHERE a = 1;
>Możesz uzyć funkcji VALUES(kolumna)
w klauzuli UPDATE
, aby odwołać się do aktualnie wstawianej wartości
wybranego pola w wierszu. Np.:
mysql> INSERT INTO tabela (a, b, c) VALUES (1, 2, 3), (4, 5, 6)
-> ON DUPLICATE KEY UPDATE c = VALUES(a) + VALUES(b);
Jest równoważne z:
mysql> INSERT INTO tabela (a, b, c) VALUES (1, 2, 3)
-> ON DUPLICATE KEY UPDATE c = 3;
mysql> INSERT INTO tabela (a, b, c) VALUES (4, 5, 6)
-> ON DUPLICATE KEY UPDATE c = 9;
Instrukcja LOAD DATA INFILE
Polecenie LOAD DATA INFILE
z bardzo szybko odczytuje wiersze z pliku tekstowego i wstawia je do tabeli.
LOAD DATA [LOW_PRIORITY] [LOCAL] INFILE 'nazwa_pliku.txt'
[REPLACE | IGNORE]
INTO TABLE nazwa_tabeli
[FIELDS
[TERMINATED BY ' ']
[[OPTIONALLY] ENCLOSED BY '']
[ESCAPED BY '\' ]
]
[LINES TERMINATED BY '
']
[IGNORE n LINES]
[(nazwa_kolumny,...)]
Jeżeli podano słowo kluczowe LOCAL
, plik jest odczytywany z hosta klienta. Jeżeli nie, plik musi znajdować się na serwerze.
Ze względów bezpieczeństwa, jeżeli plik odczytywany jest z serwera, musi albo znajdować się w katalogu bazy danych albo mieć
ustawione prawa do odczytu przez każdego. Musisz mieć też prawo file na hoscie serwera.
Jeżeli zastosujesz słowo kluczowe LOW_PRIORITY
, wykonanie polecenia LOAD DATA
zostanie odroczone do momentu
kiedy żaden inny klient nie będzie odczytywał danych z tabeli.
Użycie LOCAL
będzie wolniejsze niż pozwolenie serwerowi na bezpośredni dostęp do pliku, ponieważ jego zawartość musi
zostać przetransportowana od hosta klienta do hosta serwera. Z drugiej strony nie musisz posiadać prawa file
do wykonania tej operacji.
Słowa kluczowe REPLACE
i IGNORE
kontrolują sposób traktowania rekordów wejściowych dublujących
istniejące rekordy w kluczach unikatowych. Przy użyciu REPLACE
nowe wiersze zastępują istniejące o tych samych
wartościach klucza. Jeżeli natomiast użyjesz IGNORE
, wiersze te są pomijane. Jeżeli nie zastosujesz żadnej
z tych opcji, po napotkaniu identycznej wartości w polu klucza wystąpi błąd, a reszta pliku jest pomijana.
Jeżeli wczytujesz dane z pliku lokalnego przy użyciu słowa kluczowego LOCAL
serwer nie ma możliwości zatrzymania
transmisji pliku w czasie trwania operacji, więc domyślnym zachowanie jest takie, jakby użyto opcji IGNORE
.
Jeżeli zastosujesz polecenie LOAD DATA INFILE
do pustej tabeli, to wszystkie nie unikatowe indeksy są tworzone
w oddzielnych zadaniach. Czyni to LOAD DATA INFILE
znacznie szybszym jeżeli masz wielu indeksów.
LOAD DATA INFILE
jest uzupełnieniem SELECT ... INTO OUTFILE
. Aby zapisać dane z bazy do pliku,
użyj SELECT ... INTO OUTFILE
. Aby z powrotem wczytać dane do bazy, użyj LOAD DATA INFILE
.
Składnia klauzul FIELDS
i LINES
w obu poleceniach jest taka sama. Obie te klauzule są
opcjonalne, ale w obu przypadkach FIELDS
musi poprzedzać LINES
.
Jeżeli zastosujesz klauzulę FIELDS
, każda jej podklasa (TERMINATED BY
, [OPTIONALLY] ENCLOSED BY
i ESCAPED BY
) jest również opcjonalna, ale musisz określić przynajmniej jedną z nich.
Jeżeli nie zastosujesz klauzuli FIELDS
domyślnie stosowane są takie ustawienia, jakbyś zapisał:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
Jeżeli nie zastosujesz klauzuli LINES
domyślnie stosowane są takie ustawienia, jakbyś zapisał:
LINES TERMINATED BY '\n'
Czyli domyślnie LOAD DATA INFILE
przy wczytywaniu pliku wejściowego działa następująco:
- wiersze są kończone znakiem nowego wiersza;
- pola w wierszu oddzielane są tabulatorami;
- wartości pól nie są umieszczone w cudzysłowach;
- znaki tabulatora, nowego wiersza lub '\' poprzedzonej znakiem '\' traktowane są jak literały
łańcuchowe będące częścią wartości pola
Podobnie SELECT ... INTO OUTFILE
przy zapisywaniu pliku wyjściowego ma ustawienia domyślne:
- zapisuje tabulatory między polami;
- nie zamyka wartości pól w cudzysłowie;
- stosuje znak '\' do oznaczenia pierwotnego znaczenia znaków tabulatora, nowego wiersza lub '\'
występujących w wartościach pola;
- zapisuje znak nowego wiersza na końcu każdego wiersza tabeli.
Pamiętaj, że aby zapisać FIELDS ESCAPED BY '\\'
musisz podać dwa znaki '\', jeżeli mają one być przeczytane
jako jeden.
Opcja IGNORE n LINES
pozwala na zignorowanie n wierszy z początku pliku:
LOAD DATA INFILE "/tmp/nazwa_pliku" INTO tabela test IGNORE 1 LINES;
Jeżeli użyjesz SELECT ... INTO OUTFILE
w połączeniu z LOAD DATA INFILE
do zapisu danych z bazy do pliku,
a następnie do odczytu z pliku do bazy, opcje obsługi pól i wierszy muszą być zgodne. W przeciwnym wypadku,
LOAD DATA INFILE
nie zinterpretuje poprawnie zawartości pliku zapisanego wcześniej. Przypuśćmy, że użyjesz
SELECT ... INTO OUTFILE
do zapisu danych do pliku z opcją oddzielania pól znakiem ',':
SELECT * INTO OUTFILE 'dane.txt'
FIELDS TERMINATED BY ','
FROM ...
Aby odczytać z powrotem pola rozdzielone przecinkami, prawidłowe polecenie powinno wyglądać następująco:
LOAD DATA INFILE 'dane.txt' INTO TABLE tabela2
FIELDS TERMINATED BY ',';
LOAD DATA INFILE
może być też użyte do odczytu plików pozyskanych ze źródeł zewnętrznych. Na przykład, plik w formacie
dBASE będzie miał format pól oddzielanych przecinkami i wartościami zawartymi w podwójnych cudzysłowach. Jeżeli wiersze w pliku
zakończone są znakiem nowego wiersza, to poniższe polecenie obrazuje poprawny sposób obsługi pól i wierszy w celu wczytania
takiego pliku:
LOAD DATA INFILE 'data.txt' INTO TABLE nazwa_tabeli
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';
Każda z opcji obsługi wiersza lub pola może zawierać pusty łańcuch (''
). Jeżeli łańcuch nie jest pusty, wartość
FIELDS [OPTIONALLY] ENCLOSED BY
i FIELDS ESCAPED BY
musi być pojedynczym znakiem. Wartością
FIELDS TERMINATED BY
i LINES TERMINATED BY
może być więcej niż 1 znak. Np.: aby zapisać wiersze zakończone
parą znaków 'CR-LF' lub odczytać plik zawierająca wiersze w tym formacie, użyj klauzuli
LINES TERMINATED BY '\r\n'
.
Opcja FIELDS [OPTIONALLY] ENCLOSED BY
kontroluje otaczanie pól cudzysłowami. Przy zapisie
(SELECT ... INTO OUTFILE
), jeżeli pominiesz słowo OPTIONALLY
, wszystkie pola zostaną otoczone znakiem
ENCLOSED BY
. Jeżeli podasz OPTIONALLY
, to znak ENCLOSED BY
używany jest tylko do otoczenia
pól typu CHAR
i VARCHAR
.
Klauzula FIELDS ESCAPED BY
określa sposób zapisu i odczytu znaków specjalnych. Jeżeli wartość ta nie jest pusta,
poprzedza ona następujące znaki przy zapisie pliku wyjściowego:
- znak
FIELDS ESCAPED BY
;
- znak
FIELDS [OPTIONALLY] ENCLOSED BY
;
- pierwszy znak wartości
FIELDS TERMINATED BY
i LINES TERMINATED BY
;
- kod ASCII w wartości NULL.
Jeżeli wartość FIELDS ESCAPED BY
jest pusta, żadne znaki nie są poprzedzane. Zazwyczaj nie jest to dobry pomysł,
szczególnie jeżeli wartości pól danych zawierają któryś ze znaków z powyższej listy.
W przypadku pliku wejściowego, jeżeli znak FIELDS ESCAPED BY
nie jest pusty, jego wystąpienia są usuwane,
a następny znak jest interpretowany dosłownie jako część wartości pola. Wyjątkami są znaki '0' lub 'n'
(na przykład, \0
lub \n
przy znaku ucieczki zdefiniowanym jako '\').
W pewnych warunkach, opcje obsługi wierszy i pól mogą na siebie wpływać:
- jeżeli zdefiniowane
FIELDS TERMINATED BY
, a nie zdefiniowano LINES TERMINATED BY
to wiersze,
podobnie jak pola, kończone są znakiem FIELDS TERMINATED BY
;
- jeżeli zarówno
FIELDS TERMINATED BY
jak i FIELDS ENCLOSED BY
są niezdefiniowane (''
),
to stosowany jest format o stałej długości wiersza, bez znaków ograniczających . Zamiast tego, wartości kolumn są zapisywane
i odczytywane przy użyciu stałej szerokości kolumny. Na przykład, jeżeli kolumna została zadeklarowana jako INT(7)
,
wartości w tej kolumnie zapisywane są do pola o długości 7 znaków. Przy odczycie, wartości tej kolumny wyznaczane są przez
odczyt 7 znaków. Format o stałej długości wpływa też na obsługę wartości NULL.
Obsługa wartości NULL rożni się w zależności od użytych opcji FIELDS
LINES
:
- przy domyślnych wartościach
FIELDS
i LINES
, NULL zapisywany jest jako \N
,
natomiast przy odczycie znaki \N
traktowane są jako wartość NULL (przy założeniu, że znakiem
ESCAPED BY
jest '\');
- jeżeli zdefiniowana została klauzula
FIELDS ENCLOSED BY
, to polu, którego wartością jest słowo NULL,
przypisana zostaje wartość NULL (inaczej jest w przypadku, gdy słowo NULL otoczone jest znakami
FIELDS ENCLOSED BY
, wtedy wartością tego pola jest łańcuch 'NULL'
);
- jeżeli klauzula
FIELDS ESCAPED BY
pozostaje pusta, to NULL zostaje zapisane jako słowo NULL;
- w przypadku formatu o stałej długości wiersza, który stosowany jest w przypadku pustych wartości
FIELDS TERMINATED BY
i FIELDS ENCLOSED BY
), NULL zapisywany jest jako łańcuch pusty. Pamiętaj, że powoduje to, iż wartości
NULL i puste łańcuchy w tabeli są nieodróżnialne przy zapisie do pliku. Jeżeli potrzebujesz możliwości rozróżniania
tych dwóch zapisów przy odczycie, nie powinieneś stosować tego formatu.
Instrukcja REPLACE
Polecenie REPLACE
działa tak, jak INSERT
z tym wyjątkiem, że jeżeli zastępowany rekord ma taką samą
wartość unikatowego indeksu co rekord wstawiany, to przed wstawieniem nowego rekordu istniejący jest usuwany.
Innymi słowy, z poziomu instrukcji REPLACE
nie ma dostępu do wartości zastępowanego wiersza.
Instrukcja SELECT
span style="color: #ff0000;">'nazwa_pliku' opcje eksportu | INTO DUMPFILE 'nazwa_pliku'#]
[FOR UPDATE | LOCK IN SHARE MODE]]
Instrukcja SELECT
jest używana do pobrania wierszy z jednej lub kilku tabel. Może być użyta łącznie z klauzulą
UNION
lub podzapytaniami.
Każde wyrażenie_select
odpowiada jednej pobieranej kolumnie.
lista_tabel
oznacza jedna lub więcej tabel, z których pobieramy wiersze.
warunek
w klauzuli WHERE
jest wyrażeniem warunkowym, którego spełnienie jest warunkiem pobrania wiersz
do wyniku.
SELECT
może być użyte do pobrania wierszy bez użycia żadnej tabeli, np.:
mysql> SELECT 1 + 1;
-> 2
Jeżeli używasz jakichkolwiek klauzul instrukcji SELECT
, to muszą one zawsze występować w kolejności takiej, jak podano
w składni. Np. HAVING
musi wystąpić po GROUP BY
, ale przed ORDER BY
.
Pole może posiadać swój alias, który będzie używany jako nagłówek kolumny oraz możesz go używać w klauzulach
GROUP BY
, ORDER BY
i HAVING
, ale nie wolno używać aliasów w warunkach klauzuli
WHERE
, ponieważ warunek jest sprawdzany przed wybraniem pól. Np.:
mysql> SELECT CONCAT(imie,' ',nazwisko) AS kto
-> FROM tabela ORDER BY kto;
Klauzula FROM
podaje tabele (jedną lub więcej), z których mają być pobrane wiersze. Jeżeli podasz więcej niż jedną
tabelę, to automatycznie wykonywana jest klauzula złączenia tabel JOIN
. Tabele - podobnie jak pola - mogą
posiadać aliasy. Pełna składnia dla każdej tabeli wygląda tak:
nazwa_tabeli [[AS] alias]
[[USE INDEX (lista_kluczy)]
| [IGNORE INDEX (lista_kluczy)]
| [FORCE INDEX (lista_kluczy)]]
Użycie słów kluczowych USE INDEX, IGNORE INDEX, FORCE INDEX
służy optymalizacji wyboru używanych indeksów tabeli.
Możesz odwołać się do tabeli bieżącej bazy danych podając tylko jej nazwę lub do tabeli z innej bazy podając bazę, w której tabela
się znajduje: nazwa_bazy.nazwa_tabeli
. Do kolumn możesz odwoływać się na 3 sposoby:
nszwa_pola
nazwa_tabeli.nszwa_pola
nazwa_bazy.nazwa_tabeli.nszwa_pola
Na ogół wystarcza podanie nazwy pola. Jeżeli jednak taka sama nazwa występuje w kilku tabelach instrukcji SELECT
,
to MySQL musi je czymś rozróżnić: wtedy musisz dodatkowo podać nazwę tabeli i ewentualnie bazy danych.
Możesz podać słowo kluczowe DUAL
dla oznaczenia nieistniejącej tabeli:
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
Użycie aliasów tabel pokazuje poniższy przykład:
mysql> SELECT t1.id, t2.haslo FROM dane AS t1, slownik AS t2
-> WHERE t1.id = t2.id;
W klauzuli WHERE
możesz używać wszystkich funkcji MySQL z wyjątkiem funkcji agregacji.
Kolumny używane w klauzulach ORDER BY
i GROUP BY
możesz definiować podając ich nazwy, aliasy lub
pozycję na liście (pozycje kolumn numerowane są od 1):
mysql> SELECT lp, nazwisko, imie FROM osoby
-> ORDER BY nazwisko, imie;
mysql> SELECT lp, nazwisko AS n, imie AS i FROM osoby
-> ORDER BY n, i;
mysql> SELECT lp, nazwisko, imie FROM osoby
-> ORDER BY 2, 3;
Aby wynik posortować malejąco użyj słowa kluczowego DESC
za odpowiednią kolumna w klauzuli ORDER BY
.
Domyślnie dane są sortowane rosnąco, ale możesz to również zapisać używając słowa kluczowego ASC
.
Jeżeli używasz klauzuli GROUP BY
, to wynik jest sortowany rosnąco według kolumn użytych w GROUP BY
.
Klauzula HAVING
może być użyta tylko łącznie z klauzulą GROUP BY
. Służy do wybrania tylko tych
wyników grupowania, które spełniają podany warunek. HAVING
działa podobnie do WHERE
, ale nie bezpośrednio
na rekordach tabeli, tylko na zgrupowanych rekordach (obie klauzule - mimo podobieństw - nie mogą być używane wymiennie).
W odróżnieniu od klauzuli WHERE
klauzula HAVING
może używać funkcji agregacji:
Klauzula LIMIT
może być użyta do określenia ilości wierszy zwracanych przez instrukcje SELECT
.
LIMIT
może składać się z jednej lub 2 liczb całkowitych. Jeżeli podasz tylko jedną liczbę, to oznacza ona ilość
zwracanych wierszy, przy czym zawsze brane są początkowe wiersze. Jeżeli podasz dwie liczby, to 1-sza podaje numer
pierwszego zwracanego wiersza, a 2-ga - ile wierszy ma być zwróconych. Np.:
mysql> SELECT * FROM tabela LIMIT 5;
# Zwroci 5 pierwszych wierszy
mysql> SELECT * FROM tabela LIMIT 5,10;
# Zwroci wiersze 6 - 15
SELECT ... INTO OUTFILE 'nazwa_pliku'
zapisuje wynik do podanego pliku. Plik jest zakładany na serwerze, musisz więc
posiadać uprawnienia do tworzenia plików. Plik nie może istnieć, co ma zapobiegać możliwości nadpisywania plików systemowych.
Ten sposób wybierania wierszy pozwala na bardzo szybkie utworzenie kopii danych z bazy.
Zapis danych z tabeli do pliku odbywa się zgodnie ze specyfikacją instrukcji LOAD DATA INFILE
: pola wiersza
oddzielana są znakiem tabulacji, a kolejne wiersze znakiem nowej linii (o ile nie zdefiniujesz innych własnych znaków).
Klauzula INTO DUMPFILE
zapisuje do pliku tylko jeden rekord i nie używa żadnych separatorów. Może to być
użyteczne przy zapisie dużych pół tekstowych (TEXT, MEDIUMTEXT, LONGTEXT). Plik - podobnie jak w przypadku
INTO OUTFILE
- zapisywany jest po stronie serwera.
Klauzula FOR UPDATE
blokuje możliwość aktualizacji tabeli przez innych klientów do momentu zakończenia
wykonywania instrukcji. Klauzula LOCK IN SHARE MODE
blokuje dodatkowo możliwość usuwania wierszy z tabeli
przed zakończeniem wykonania zapytania.
Opcje ALL, DISTINCT, DISTINCTROW
określają sposób traktowania duplikatów wierszy wyniku.
Brak którejkolwiek z tych opcji jest równoważne podaniu ALL
(wyświetlane sa wszystkie wiersze).
DISTINCT
i DISTINCTROW
są synonimami i oznaczają, że w przypadku wystąpienia
wierszy o identycznych wartościach, wyświetlany jest tylko pierwszy z nich.
Instrukcja TRUNCATE
TRUNCATE nazwa_tabeli
Polecenie spełnia tą samą funkcję co DELETE FROM nazwa_tabeli
.
Różnice między tymi poleceniami polega na tym, że TRUNCATE
:
- działa przez usunięcie i stworzenie od nowa tabeli, co jest znacznie szybsze przy usuwaniu dużej ilości wierszy;
- nie zapewnia bezpieczeństwa transakcji; automatycznie zakończy bieżącą transakcję tak, jakby wywołane zostało
polecenie
COMMIT
;
- nie zwraca liczby usuniętych wierszy;
- tabela może zostać odtworzona tak długo, jak długo istnieje poprawny plik nazwa_tabeli.frm,
nawet jeżeli pliki danych lub indeksów zostały uszkodzone.
Instrukcja UPDATE
Polecenie UPDATE
nadaje polom w wierszach istniejącej tabeli nowe wartości.
span style="color: #808080; font-style: italic;">#]
Klauzula SET
wskazuje, które kolumny należy zmodyfikować oraz podaje wartości, jakie mają zostać im przypisane.
Klauzula WHERE
, jeżeli występuje, określa wiersze do modyfikacji. Brak tej klauzuli oznacza zmianę wartości
we wszystkich wierszach tabeli.
Jeżeli podasz słowo kluczowe LOW_PRIORITY
, to wykonywanie polecenia UPDATE
zostanie odłożone do czasu,
kiedy żaden inny klient nie będzie czytał tabeli.
Jeżeli podasz słowo kluczowe IGNORE
, to proces uaktualniania nie zostanie przerwany nawet, jeżeli wystąpią błędy
związane z duplikatami kluczy. Wiersze powodujące taki konflikt nie zostaną zaktualizowane.
Jeżeli chcesz użyć wartości z tabeli nazwa_tabeli
w wyrażeniu, to musisz pamiętać, że instrukcja UPDATE
weźmie bieżącą wartość kolumny. Np.: poniższe polecenie przypisze kolumnie wiek
wartość o jeden większą, niż wynosi
jej obecna wartość:
UPDATE dane_osobowe SET wiek = wiek + 1;
Przypisania UPDATE
rozwijane są od lewej do prawej. Np.: poniższe polecenie najpierw podwaja wartość kolumny
wiek
, a następnie zwiększa ją o jeden:
UPDATE dane_osobowe SET wiek = wiek * 2, wiek = wiek + 1;
Jeżeli będziesz próbował nadać kolumnie wartość taką samą jak ta, którą obecnie posiada, to MySQL nie wykona żadnej operacji.
UPDATE
zwraca liczbę wierszy, które zostały zaktualizowane.
Możesz użyć klauzuli LIMIT #
do wymuszenia dokonania aktualizacji tylko określonej liczbie wierszy.
Instrukcja UPDATE
z klauzulą ORDER BY
określa kolejność modyfikowania rekordów z tabeli.