Potrzebuję utworzyć funkcję w SQL Server 2008, która będzie naśladować mysql's UNIX_TIMESTAMP()
.UNIX_TIMESTAMP w SQL Server
Z góry dziękuję!
Potrzebuję utworzyć funkcję w SQL Server 2008, która będzie naśladować mysql's UNIX_TIMESTAMP()
.UNIX_TIMESTAMP w SQL Server
Z góry dziękuję!
Spróbuj tego posta: http://skinn3r.wordpress.com/2009/01/26/t-sql-datetime-to-unix-timestamp/
CREATE FUNCTION UNIX_TIMESTAMP (
@ctimestamp datetime
)
RETURNS integer
AS
BEGIN
/* Function body */
declare @return integer
SELECT @return = DATEDIFF(SECOND,{d '1970-01-01'}, @ctimestamp)
return @return
END
lub tego posta:
kod jest w następujący sposób: Wykorzystanie
CREATE FUNCTION dbo.DTtoUnixTS
(
@dt DATETIME
)
RETURNS BIGINT
AS
BEGIN
DECLARE @diff BIGINT
IF @dt >= '20380119'
BEGIN
SET @diff = CONVERT(BIGINT, DATEDIFF(S, '19700101', '20380119'))
+ CONVERT(BIGINT, DATEDIFF(S, '20380119', @dt))
END
ELSE
SET @diff = DATEDIFF(S, '19700101', @dt)
RETURN @diff
END
próbki:
SELECT dbo.DTtoUnixTS(GETDATE())
-- or
SELECT UnixTimestamp = dbo.DTtoUnixTS(someColumn)
FROM someTable
Nekromantowanie.
ODBC-way:
DECLARE @unix_timestamp varchar(20)
-- SET @unix_timestamp = CAST({fn timestampdiff(SQL_TSI_SECOND,{d '1970-01-01'}, CURRENT_TIMESTAMP)} AS varchar(20))
IF CURRENT_TIMESTAMP >= '20380119'
BEGIN
SET @unix_timestamp = CAST
(
CAST
(
{fn timestampdiff(SQL_TSI_SECOND,{d '1970-01-01'}, {d '2038-01-19'})}
AS bigint
)
+
CAST
(
{fn timestampdiff(SQL_TSI_SECOND,{d '2038-01-19'}, CURRENT_TIMESTAMP)}
AS bigint
)
AS varchar(20)
)
END
ELSE
SET @unix_timestamp = CAST({fn timestampdiff(SQL_TSI_SECOND,{d '1970-01-01'}, CURRENT_TIMESTAMP)} AS varchar(20))
PRINT @unix_timestamp
często potrzebują uniksowego znacznika czasu z dokładnością do milisekund. Poniżej podajemy aktualny czas uniksowy jako FLOAT
; zawiń na odpowiedzi powyżej, aby uzyskać funkcję lub skonwertować dowolne ciągi.
Typ danych DATETIME
na serwerze SQL jest dobry tylko 3 ms, więc mam różne przykłady dla SQL Server 2005 i 2008+. Niestety nie ma funkcji DATEDIFF2
, więc różne sztuczki są wymagane, aby uniknąć przepełnienia liczb całkowitych, nawet z 2008+. (Nie mogę uwierzyć, że wprowadzono zupełnie nowy typ danych DATETIME2
bez ustalenia tego.)
Do regularnego starego DATETIME
, po prostu użyć kiepski obsady do pływaka, który zwraca (zmiennoprzecinkowych) liczbę dni od 1900.
Teraz wiem, w tym momencie myślisz, CO O SEKUNDACH LEAPOWYCH?!?! Ani czas systemu Windows, ani czas uniksowy naprawdę wierzą w sekundy przestępne: dzień jest zawsze 1,00000 dni dla SQL Server i 86400 sekund do unixtime. This wikipedia article omawia zachowanie uniksa podczas sekund przestępnych; Windows Wierzę, że po prostu wyświetla sekundy przestępne jak każdy inny błąd zegara. Tak więc, podczas gdy nie ma systematycznego dryfu pomiędzy tymi dwoma systemami, gdy występuje sekunda przestępna, nie zgadzają się one na poziomie podsekundowym podczas i zaraz po zakończeniu sekundy przestępnej.
-- the right way, for sql server 2008 and greater
declare @unixepoch2 datetime2;
declare @now2 Datetime2;
declare @days int;
declare @millisec int;
declare @today datetime2;
set @unixepoch2 = '1970-01-01 00:00:00.0000';
set @now2 = SYSUTCDATETIME();
set @days = DATEDIFF(DAY,@unixepoch2,@now2);
set @today = DATEADD(DAY,@days,@unixepoch2);
set @millisec = DATEDIFF(MILLISECOND,@today,@now2);
select (CAST (@days as float) * 86400) + (CAST(@millisec as float)/1000)
as UnixTimeFloatSQL2008
-- Note datetimes are only accurate to 3 msec, so this is less precise
-- than above, but works on any edition of SQL Server.
declare @sqlepoch datetime;
declare @unixepoch datetime;
declare @offset float;
set @sqlepoch = '1900-01-01 00:00:00';
set @unixepoch = '1970-01-01 00:00:00';
set @offset = cast (@sqlepoch as float) - cast (@unixepoch as float);
select (cast (GetUTCDate() as float) + @offset) * 86400
as UnixTimeFloatSQL2005;
-- Future developers may hate you, but you can put the offset in
-- as a const because it isn't going to change.
declare @sql_to_unix_epoch_in_days float;
set @sql_to_unix_epoch_in_days = 25567.0;
select (cast (GetUTCDate() as float) - @sql_to_unix_epoch_in_days) * 86400.0
as UnixTimeFloatSQL2005MagicNumber;
pływaków faktycznie domyślnie 8-bajtowy podwaja na SQL Server, a zatem przewyższa 32-bit INT
dla wielu zastosowań. (Na przykład nie zostaną przeniesione w 2038 r.)
Dla "- właściwa droga, dla serwera sql 2008 i więcej "Musiałem pomnożyć wynik przez 1000, aby usunąć miejsca dziesiętne, które tworzył.Zdobądź milisekundowy epoc po tym. Działa jak marzenie. Dzięki!! – jymbo
Jeśli nie przeszkadza o terminach przed 1970 lub precyzji milisekundy, wystarczy zrobić:
-- SQL Server
SELECT DATEDIFF(s, '1970-01-01 00:00:00', DateField)
Prawie tak proste, jak MySQL wbudowanej funkcji:
-- MySQL
SELECT UNIX_TIMESTAMP(DateField);
Inne języki (Oracle, PostgreSQL, etc): How To Get The Current Epoch Time (Unix Timestamp)
Wywołany do funkcji skalarnych wycenione mogą korzystać follwing składnię
ScriptFunkcja:
USE [database] GO
/****** obiektu. UserDefinedFunction [dbo] [UNIX_TIMESTAMP] ******/ SET ANSI_NULLS ON GO
SET QUOTED_IDENTIFIER NA GO
TWORZENIE funkcję [dbo]. [UNIX_TIMESTAMP] ( @ctimestamp DateTime ) powroty całkowitychCO UŻYCIEM /* treść funkcji */ DEKLARUJĄ @return całkowitą
SELECT @return = DATEDIFF (DRUGI {d '1970-01-01'} @ctimestamp)
powrotu @return END GO
Funkcja połączenia: SELECT dbo.UNIX_TIMESTAMP (GETDATE());
Próbowałem już pierwszego. wykonywanie "SELECT UNIX_TIMESTAMP (GETDATE());" zwraca "" UNIX_TIMESTAMP "nie jest rozpoznaną wbudowaną nazwą funkcji.". próbuje uruchomić (ponownie) zapytanie konfiguracji zwraca "Msg 2714, poziom 16, stan 3, procedura UNIX_TIMESTAMP, wiersz 12 Istnieje już obiekt o nazwie" UNIX_TIMESTAMP "w bazie danych." – TheZver
Czy próbowałeś SELECT dbo.UNIX_TIMESTAMP (GETDATE()); ? – rkosegi
Drugi działał dobrze. ale próba nadania jej nazwy "UNIX_TIMESTAMP" dała takie same wyniki, jak opisano wcześniej. czy nie ma sposobu, aby nazwać go "UNIX_TIMESTAMP"? Próbuję uniknąć modyfikowania prawie całego kodu, który musi działać z mysql AND mssql – TheZver