Ograniczniki w MySQL

165

Często widzę, że ludzie używają ograniczników. Próbowałem sam dowiedzieć się, czym są ograniczniki i jaki jest ich cel. Po 20 minutach wyszukiwania w Google nie udało mi się znaleźć satysfakcjonującej mnie odpowiedzi. Moje pytanie brzmi więc teraz: czym są ograniczniki i kiedy należy ich używać?

System.Data
źródło

Odpowiedzi:

245

Ograniczniki inne niż domyślne ;są zwykle używane podczas definiowania funkcji, procedur składowanych i wyzwalaczy, w których należy zdefiniować wiele instrukcji. Definiujesz inny separator, taki jak $$używany do definiowania końca całej procedury, ale w nim poszczególne instrukcje są zakończone przez ;. W ten sposób, gdy kod jest uruchamiany w mysqlkliencie, klient może powiedzieć, gdzie kończy się cała procedura i wykonać ją jako jednostkę, zamiast wykonywać poszczególne instrukcje wewnątrz.

Należy zauważyć, że DELIMITERsłowo kluczowe jest funkcją tylko mysqlklienta wiersza poleceń (i niektórych innych klientów), a nie zwykłą funkcją języka MySQL. Nie zadziała, jeśli spróbujesz przekazać go przez interfejs API języka programowania do MySQL. Niektórzy inni klienci, tacy jak PHPMyAdmin, mają inne metody określania niestandardowego separatora.

Przykład:

DELIMITER $$
/* This is a complete statement, not part of the procedure, so use the custom delimiter $$ */
DROP PROCEDURE my_procedure$$

/* Now start the procedure code */
CREATE PROCEDURE my_procedure ()
BEGIN    
  /* Inside the procedure, individual statements terminate with ; */
  CREATE TABLE tablea (
     col1 INT,
     col2 INT
  );

  INSERT INTO tablea
    SELECT * FROM table1;

  CREATE TABLE tableb (
     col1 INT,
     col2 INT
  );
  INSERT INTO tableb
    SELECT * FROM table2;
  
/* whole procedure ends with the custom delimiter */
END$$

/* Finally, reset the delimiter to the default ; */
DELIMITER ;

Próba użycia go DELIMITERz klientem, który go nie obsługuje, spowoduje wysłanie go do serwera, który zgłosi błąd składni. Na przykład używając PHP i MySQLi:

$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$result = $mysqli->query('DELIMITER $$');
echo $mysqli->error;

Błędy z:

Masz błąd w składni SQL; sprawdź podręcznik, który odpowiada Twojej wersji serwera MySQL, aby uzyskać właściwą składnię, której należy użyć w pobliżu „DELIMITER $$” w wierszu 1

Michaela Berkowskiego
źródło
3
Jakie są scenariusze, w których sensowne jest użycie separatora? Naprawdę tego nie rozumiałem.
System.Data
2
@ System.Data Pierwsze zdanie mojej odpowiedzi - podczas definiowania procedur składowanych, funkcji niestandardowych i wyzwalaczy. Za każdym razem, gdy wiele instrukcji jest wykonywanych jako jednostka w wierszu poleceń MySQL.
Michael Berkowski,
2
Zauważ, że polecenie DELIMITER nie działa z SQL PhpMyAdmin (przynajmniej niektóre wersje). Zamiast tego można ustawić separator w oddzielnym polu do samego kodu SQL. Przez jakiś czas byłem zdezorientowany ... :-)
Bardzo nieregularny
1
@MichaelBerkowski, Miejmy nadzieję, że uda nam się to zrobić w przyszłości.
Pacerier,
1
@StockB W tej odpowiedzi nie chodziło o to, dlaczego procedury składowane są korzystne, wzmianka o „jednej jednostce” odnosiła się do tego, jak MySQL byłby w stanie zinterpretować SP podczas jej analizowania: zlokalizuj granice jednostek za pomocą separatora, a następnie przeanalizuj poszczególne instrukcje wewnątrz. Ale skoro o to zapytałeś, użycie SP z wieloma instrukcjami pozwoliłoby na ukrycie szczegółów implementacji przed aplikacją wywołującą SP. Kod aplikacji nie musi zajmować się tym, jaki SQL jest wykonywany (iw razie potrzeby można to zmienić), o ile zwraca spójny wynik. Podobnie jak funkcja w kodzie.
Michael Berkowski
21

Instrukcja DELIMITER zmienia standardowy separator, którym jest średnik (;), na inny. Separator został zmieniony ze średnika (;) na podwójne ukośniki //.

Dlaczego musimy zmienić ogranicznik?

Ponieważ chcemy przekazać procedurę składowaną, funkcje niestandardowe itp. Do serwera jako całość, zamiast pozwalać narzędziu mysql na interpretowanie każdej instrukcji na raz.

Pradeep Singh
źródło
13

Podczas tworzenia procedury składowanej, która ma BEGIN...ENDblok, instrukcje w bloku są zakończone średnikiem (;). Ale CREATE PROCEDUREinstrukcja wymaga również terminatora. Staje się więc niejednoznaczne, czy średnik w treści procedury kończy CREATE PROCEDURE, czy kończy jedno z instrukcji w treści procedury.

Sposobem na rozwiązanie tej niejednoznaczności jest zadeklarowanie odrębnego ciągu znaków (który nie może występować w treści procedury), który klient MySQL rozpoznaje jako prawdziwy terminator CREATE PROCEDUREinstrukcji.

Rizwan Ahmed
źródło
1
Jest to najlepsza odpowiedź, ponieważ podaje prawidłowy powód użycia DELIMITER w najprostszy sposób i bez powodowania zamieszania. Dzięki
Fakhar Anwar
6

Separator to znak lub ciąg znaków, których użyjesz do poinformowania klienta MySQL, że zakończyłeś wpisywanie instrukcji Sql.

Kaumadie Kariyawasam
źródło
5

Definiujesz DELIMITER, aby poinformować klienta mysql, aby traktował instrukcje, funkcje, procedury składowane lub wyzwalacze jako całą instrukcję. Zwykle w pliku .sql ustawia się inny DELIMITER, np. $$. Polecenie DELIMITER służy do zmiany standardowego separatora poleceń MySQL (tj.;). Ponieważ instrukcje w ramach procedur (funkcji, procedur składowanych lub wyzwalaczy) kończą się średnikiem (;), aby traktować je jako instrukcję złożoną, używamy DELIMITER. Jeśli nie zostanie zdefiniowany podczas używania różnych procedur w tym samym pliku lub linii poleceń, spowoduje błąd składni.

Pamiętaj, że możesz użyć różnych niezarezerwowanych znaków, aby utworzyć własny, niestandardowy separator. Należy unikać używania znaku ukośnika odwrotnego (\), ponieważ jest to znak zmiany znaczenia dla MySQL.

DELIMITER tak naprawdę nie jest poleceniem języka MySQL, jest to polecenie klienta.

Przykład

DELIMITER $$

/*This is treated as a single statement as it ends with $$ */
DROP PROCEDURE IF EXISTS `get_count_for_department`$$

/*This routine is a compound statement. It ends with $$ to let the mysql client know to execute it as a single statement.*/ 
CREATE DEFINER=`student`@`localhost` PROCEDURE `get_count_for_department`(IN the_department VARCHAR(64), OUT the_count INT)
BEGIN
    
    SELECT COUNT(*) INTO the_count FROM employees where department=the_department;

END$$

/*DELIMITER is set to it's default*/
DELIMITER ;
Optimizer
źródło
Możesz dodać separator, aby zdefiniować zakres kodu procedury mysql. Aby uzyskać więcej szczegółów, zapoznaj się z ostatnią sekcją mojego samouczka techflirt.com/mysql-stored-procedure-tutorial
Ankur Kumar Singh
1

DELIMITER, aby poinformować klienta mysql, aby traktował instrukcje, funkcje, procedury składowane lub wyzwalacze jako całą instrukcję. Zwykle w. sql, ustawisz inny DELIMITER, na przykład $$. Polecenie DELIMITER służy do zmiany standardowego separatora poleceń MySQL

Vihanga Sahan
źródło
1

Separator to znak w języku SQL, który służy do oddzielania elementów danych w bazie danych. Określa początek i koniec ciągu znaków. Ogólnie separatorem używanym w SQL jest „;”.

Wenusara Kappetige
źródło