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

Jak zwrócić uniksową sygnaturę czasową w SQL Server (T-SQL)

Być może zauważyłeś, że SQL Server nie ma odpowiednika UNIX_TIMESTAMP() MySQL funkcja.

Jednak nie jest tak trudno zwrócić uniksową sygnaturę czasową w SQL Server.

Znacznik czasu Unix (znany również jako czas Epoki Unix, czas Unix lub czas POSIX) to po prostu liczba sekund, które upłynęły od 00:00:00 w czwartek, 1 stycznia 1970 r., Uniwersalny czas koordynowany (UTC). Dlatego w SQL Server możemy użyć kilku funkcji T-SQL, aby to zwrócić.

sygnatura czasowa uniksowego serwera SQL

Oto jak możesz zwrócić uniksowy znacznik czasu w SQL Server.

SELECT DATEDIFF(SECOND,'1970-01-01', GETUTCDATE()) AS 'SQL Server Result';

Wynik:

+---------------------+
| SQL Server Result   |
|---------------------|
| 1560833178          |
+---------------------+

Możemy więc użyć DATEDIFF() funkcja zwracająca różnicę w sekundach między 1970-01-01 a teraz. Używamy GETUTCDATE() funkcja zwracająca bieżącą datę i godzinę w czasie UTC.

Ten kod będzie działał do roku 2038 (dokładnie ‘2038-01-19 03:14:07’). W przypadku uniksowych znaczników czasu po tym, będziesz musiał nieznacznie zmodyfikować kod. Jeśli potrzebujesz znacznika czasu uniksowego po tej dacie, czytaj dalej.

Odpowiednik sygnatury czasowej MySQL Unix

Dla porównania, jeśli uruchomię UNIX_TIMESTAMP() MySQLa dokładnie w tym samym czasie otrzymuję to:

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Wynik:

+--------------+
| MySQL Result |
+--------------+
|   1560833178 |
+--------------+

Ten sam wynik. MySQL zwraca wynik jako liczbę całkowitą bez znaku. Jeśli jednak (opcjonalny) argument data zostanie przekazany, obsługuje ten sam zakres, co TIMESTAMP typ danych.

Zwróć milisekundy

Jeśli chcesz zwrócić uniksowy znacznik czasu z większą precyzją, powiedzmy liczbę milisekund od ‘1970-01-01 00:00:00.000’ UTC, będziesz musiał zamienić DATEDIFF() funkcja dla DATEDIFF_BIG() .

Dzieje się tak, ponieważ DATEDIFF() zwraca int , który jest zbyt mały, aby obsłużyć liczbę milisekund od 1970 roku. Funkcja DATEDIFF_BIG() z drugiej strony funkcja zwraca podpisany bigin , co jest więcej niż wystarczające do obsługi milisekund.

SELECT DATEDIFF_BIG(MILLISECOND,'1970-01-01 00:00:00.000', SYSUTCDATETIME()) Milliseconds;

Wynik:

+----------------+
| Milliseconds   |
|----------------|
| 1560835305461  |
+----------------+

Zwróć nanosekundy

Oto kolejny przykład, tym razem idący aż do nanosekund od „1970-01-01 00:00:00.0000000” UTC.

SELECT DATEDIFF_BIG(NANOSECOND,'1970-01-01 00:00:00.0000000', SYSUTCDATETIME()) Nanoseconds;

Wynik:

+---------------------+
| Nanoseconds         |
|---------------------|
| 1560835321500279300 |
+---------------------+

Problem roku 2038

Zwracanie milisekund, mikrosekund i nanosekund jest dobre i dobre, ale ściśle mówiąc, nie jest to prawdziwy czas epoki Uniksa. Czas epoki Uniksa to liczba sekund od ‘1970-01-01 00:00:00’.

Jednak DATEDIFF_BIG() nadal może się przydać podczas zwracania ścisłego czasu Unix Epoch. W szczególności może to pomóc Twojej bazie danych w rozwiązaniu problemu 2038. W takim przypadku wszystko po „2038-01-19 03:14:07” będzie musiało zostać zwrócone jako bigint (8-bajtowa liczba całkowita). Dzieje się tak, ponieważ liczba sekund będzie zbyt duża dla int typ danych (4 bajtowa liczba całkowita). int typ danych wzrasta tylko do 2147483647, podczas gdy bigint wzrasta do 9 223 372 036 854 775 807.

Dlatego, aby zwrócić uniksowe znaczniki czasu po „2038-01-19 03:14:07”, użyj DATEDIFF_BIG() funkcja zamiast DATEDIFF() .

Aby to zademonstrować, oto przykład użycia DATEDIFF() aby zwrócić czas uniksowy dokładnie w tym dniu/czasie:

SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:07') AS 'Unix Epoch time';

Wynik:

+-------------------+
| Unix Epoch time   |
|-------------------|
| 2147483647        |
+-------------------+

Jak na razie dobrze. Ten wynik mieści się w int zakres od -2 147 483 648 do 2 147 483 647 (chociaż mieści się w górnym limicie), więc zwracany jest poprawny wynik.

Ale oto, co się stanie, jeśli zwiększymy go o jedną sekundę:

SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';

Wynik:

The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

Otrzymujemy błąd, ponieważ zwrócona wartość byłaby poza int zasięg.

Jak już wspomniano, wszystko, co musimy zrobić, to zamienić DATEDIFF() dla DATEDIFF_BIG() :

SELECT DATEDIFF_BIG(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';

Wynik:

+-------------------+
| Unix Epoch time   |
|-------------------|
| 2147483648        |
+-------------------+

Jednak niekoniecznie rozwiąże to wszystkie problemy z roku 2038, ponieważ większość potencjalnych problemów prawdopodobnie wynikałaby z systemu operacyjnego.

Powinienem również zaznaczyć, że żaden z tych kodów niekoniecznie będzie odporny na „Problem 10 000 roku”, ponieważ obejmuje on datetime2 typ danych, który ma górny zakres „9999-12-31”.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Klauzula wyjściowa SQL Server do zmiennej skalarnej

  2. Dynamiczne tabele T-SQL i tabele temp

  3. Jak zmienić nazwę bazy danych SQL Server za pomocą T-SQL

  4. Porównanie ciągów SQL uwzględniających wielkość liter

  5. Co to jest procedura składowana?