Natrafiłem niedawno na całkiem nudny przypadek z cudzysłowami w skrypcie T-SQL, którym - z braku jakiegoś bardziejszego laku - niniejszym dzielę się z pleno titulo czytawcami i czytajkami. A nuż się przyda.
Zaczniemy od początku:
declare @d1 date = '2021-01-01';
Proste. Deklarujemy zmienną d1
, typu data, z wartością ustawioną na początek 2021 roku.
A teraz spróbujmy skonstruować dynamiczne zapytanie SQL używające ww. zmiennej i zapisać je do innej zmiennej:
declare @zapytanie nvarchar(max) = 'SELECT * FROM jakas_tabelka where jakies_pole = ''' + @d1 + ''';'
Tutaj zmienna d1
jest już otoczona płotkiem z trzech ciapków po każdej stronie, bo tak się cytuje ciapki w SQL-u (podwaja się je).
A teraz spróbujmy skonstruować dynamiczne zapytanie SQL, które będziemy uruchamiać na serwerze zdalnym za pomocą operatora OPENQUERY
:
declare @openquery_sql nvarchar(max) = 'SELECT * FROM OPENQUERY([zdalny_serwer], ''SELECT * FROM jakas_tabelka where jakies_pole = ''''' + @d1 + ''''';'')'
Tutaj wokół zmiennej d1
powstał już popiątny ostrokół, ponieważ cytujemy w cytacie.
Wszystko jasne?
Nie do końca jasne? No dobra. Spróbujmy zatem pobawić się kredkami:
Oryginalne zapytanie, apostrofy wokół daty pomalowane na zielono:
declare @d1 date = '2021-01-01';
Zapytanie dynamiczne, apostrofy wokół daty nadal pomalowane na zielono, apostrofy wokół całej zmiennej - na różowo:
declare @zapytanie nvarchar(max) = 'SELECT * FROM jakas_tabelka where jakies_pole = ''' + @d1 + ''';'
Wreszcie najbardziej pozagnieżdżana wersja: cała zmienna @openquery_sql
otoczona pomarańczowymi ciapkami, a zielone i różowe się rozmnożyły:
declare @openquery_sql nvarchar(max) = 'SELECT * FROM OPENQUERY([zdalny_serwer], ''SELECT * FROM jakas_tabelka where jakies_pole = ''''' + @d1 + ''''';'')'
Nie wiem jak reszta świata, ale ja tego typu zapytania zawsze tworzę metodą prób i błędów (z przewagą tych ostatnich).
A dla nie sponiewieranych SQLem, co to są dynamiczne zapytania?
Pytanie z perspektywy osoby, która kojarzy podstawy PHP i MySQL
Dynamiczne zapytanie SQL to komenda, która nie jest zapisana bezpośrednio w kodzie źródłowym, tylko „zbudowana” przez ów kod. Weźmy na przykład funkcję PHP, która na wejście dostaje nazwę tabeli, a na wyjściu generuje jeden losowy rekord z tej tabeli:
W tym przykładzie, linia:
SELECT TOP 1 * FROM [$escapedTableName] ORDER BY NEWID()
to jest właśnie zapytanie dynamiczne. A więc zamiast konkretnego zapytania SQL mamy tutaj wyrażenie składające się z operatorów SQL oraz lokalnych zmiennych PHP.
Bardziej zaawansowane przykłady mogą obejmować np. włączanie lub wyłączanie całych sekcji / bloków skryptu SQL, filtrów, operatorów agregujących itd.