Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Używając GETDATE() w wielu miejscach, czy lepiej jest używać zmiennej?

[UWAGA:Jeśli zamierzasz odrzucić tę odpowiedź, zostaw komentarz wyjaśniający dlaczego. Zostało to już wielokrotnie przegłosowane, a w końcu ypercube (dziękuję) wyjaśnił przynajmniej jeden powód. Nie mogę usunąć odpowiedzi, ponieważ została zaakceptowana, więc równie dobrze możesz pomóc w jej ulepszeniu.]

Według tej wymiany na Microsoft, GETDATE() zmienił się ze stałego w zapytaniu na niedeterministyczny w SQL Server 2005. Z perspektywy czasu wydaje mi się, że nie jest to dokładne. Myślę, że było to całkowicie niedeterministyczne przed SQL Server 2005, a następnie włamano się do czegoś, co nazywa się „niedeterministyczną stałą uruchomieniową” od SQL Server 2005”. Późniejsza fraza naprawdę wydaje się oznaczać „stałą w zapytaniu”.

(I GETDATE() jest zdefiniowany jako jednoznacznie i dumnie niedeterministyczny, bez kwalifikatorów.)

Niestety, w SQL Server niedeterministyczny nie oznacza, że ​​funkcja jest oceniana dla każdego wiersza. SQL Server naprawdę czyni to niepotrzebnie skomplikowanym i niejednoznacznym z bardzo małą dokumentacją na ten temat.

W praktyce wywołanie funkcji jest oceniane, gdy zapytanie jest uruchomione, a nie raz, gdy zapytanie jest kompilowane, a jego wartość zmienia się przy każdym wywołaniu. W praktyce GETDATE() jest oceniany tylko raz dla każdego wyrażenia, w którym jest używane — w czasie wykonania zamiast czasu kompilacji . Jednak Microsoft umieszcza rand() i getdate() do specjalnej kategorii, zwanej niedeterministycznymi funkcjami stałych czasu wykonywania. W przeciwieństwie do tego, Postgres nie przeskakuje przez takie obręcze, po prostu wywołuje funkcje, które mają stałą wartość, gdy są wykonywane jako „stabilne”.

Pomimo komentarza Martina Smitha, dokumentacja SQL Server po prostu nie jest wyraźna w tej sprawie — GETDATE() jest opisany zarówno jako „niedeterministyczna”, jak i „niedeterministyczna stała czasu wykonywania”, ale ten termin nie jest tak naprawdę wyjaśniony. Jedyne miejsce, w którym znalazłem termin , na przykład, kolejne wiersze w dokumentacji mówią, aby nie używać niedeterministycznych funkcji w podzapytaniach. To byłaby głupia rada dla „niedeterministycznej stałej czasu działania”.

Sugerowałbym użycie zmiennej ze stałą nawet w zapytaniu, aby uzyskać stałą wartość. To również sprawia, że ​​intencja jest całkiem jasna:chcesz mieć pojedynczą wartość w zapytaniu. W ramach jednego zapytania możesz zrobić coś takiego:

select . . . 
from (select getdate() as now) params cross join
     . . . 

Właściwie jest to sugestia, która powinna oceniać tylko raz w zapytaniu, ale mogą istnieć wyjątki. Zamieszanie powstaje, ponieważ getdate() zwraca tę samą wartość we wszystkich różnych wierszach — ale może zwracać różne wartości w różnych kolumnach. Każde wyrażenie z getdate() jest oceniany niezależnie. Jest to oczywiste, jeśli uruchomisz:

select rand(), rand()
from (values (1), (2), (3)) v(x);

W ramach procedury składowanej chciałbyś mieć pojedynczą wartość w zmiennej. Co się stanie, jeśli procedura składowana zostanie uruchomiona o północy, a data ulegnie zmianie? Jaki ma to wpływ na wyniki?

Jeśli chodzi o wydajność, domyślam się, że wyszukiwanie daty/godziny jest minimalne, a zapytanie występuje raz na wyrażenie, gdy zapytanie zaczyna działać. To naprawdę nie powinno być problemem z wydajnością, ale raczej ze spójnością kodu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rzeczywiste a zmiennoprzecinkowe a pieniądze

  2. Nie można rozpocząć transakcji rozproszonej

  3. Jak przekonwertować obraz na tablicę bajtów za pomocą javascript tylko do przechowywania obrazu na serwerze sql?

  4. Jak utworzyć klucz obcy w SQL Server (przykłady T-SQL)

  5. Jak naprawić „wyrażenie EXECUTE nie powiodło się, ponieważ jego klauzula WITH RESULT SETS określono 2 kolumny dla zestawu wyników…” Msg 11537 w programie SQL Server