2009-07-16 7 views
10

Ich habe eine einzelne Variable char (8) formatiert als ddmmyyyy in einer gespeicherten Prozedur (Qualität und Gültigkeit dieses Wertes ist unbekannt und außerhalb meiner Kontrolle). Was ist der beste Weg, den Wert in eine Datetime-Variable zu verschieben und einen Fehler auszulösen, wenn es sich nicht um eine gültige Datetime handelt? beste Möglichkeit zum Konvertieren und Validieren einer Datumszeichenkette

DECLARE @Source  char(8) 
DECLARE @Destination datetime 

SET @Source='07152009' 

--your solution here 


SELECT @Destination 

hier ist der beste Weg, die ich denken konnte:

DECLARE @Source    char(8) 
DECLARE @Temp    varchar(10) 
DECLARE @Destination  datetime 

set @Source='07152009' 
SET @Temp=LEFT(@Source,2)+'/'+SUBSTRING(@Source,3,2)+'/'+RIGHT(@Source,4) 

IF ISDATE(@Temp)!=1 
BEGIN 
    RAISERROR('ERROR, invalid date',16,1) 
END 
SET @[email protected] 

SELECT @Source AS Source, @Temp AS Temp, @Destination AS Destination 

EDIT hier ist, was ich mit ...

DECLARE @Source    char(8) 
DECLARE @Destination  datetime 

set @Source='07152009' 
BEGIN TRY 
    SET @Destination=CONVERT(datetime,RIGHT(@Source,4)  -- YYYY 
             +LEFT(@Source,2)  -- MM 
             +SUBSTRING(@Source,3,2) -- DD 
          ) 
END TRY 
BEGIN CATCH 
    PRINT 'ERROR!!!' --I'll add a little more logic here and abort processing 
END CATCH 

SELECT @Source AS Source, @Destination AS Destination 
+0

scheint gut für mich, das ist, was ich auch geschrieben haben. Ich bin gespannt, ob es besser ist. –

Antwort

12

Zunächst einmal gehen werde, Da Sie SQL Server 2005 verwenden, sollten Sie Ihren Code setzen, möglicherweise Fehler in BEGIN TRY.....END TRY BEGIN CATCH....END CATCH Blöcke - versuchen/Blöcke für T-SQL fangen!

Zweitens, für alle Datumsmanipulation würde ich immer verwenden ISO-8601 format, die unabhängig davon, was das aktuelle Datumsformat in SQL Server festgelegt ist.

ISO-8601-Format ist YYYYMMDD für nur Daten oder YYYY-MM-DDTHH:MM:SS für Datum mit der Zeit - also würde ich Code wie schreiben:

BEGIN TRY 
    SET @Source='07152009' 
    SET @Temp = RIGHT(@Source, 4) +    -- YYYY 
       LEFT(@Source, 2) +    -- MM 
       SUBSTRING(@Source, 3, 2)  -- DD 

    IF ISDATE(@Temp)!=1 
    BEGIN 
     RAISERROR('ERROR, invalid date',16,1) 
    END 

    SET @Destination = CAST(@Temp AS DATETIME) 
END TRY 
BEGIN CATCH 
     -- handle error if something bombs out 
END CATCH 

Verlassen Sie sich nicht auf einem bestimmtes Datumsformat eingestellt wird !! Senden Sie mir Ihren Code und ich werde es auf einem schweizerisch-deutschen System versuchen - ich garantiere fast, es wird brechen, wenn Sie blind annehmen "en-US" und somit "mm/dd/yyyy" - es ist nicht die gleiche Einstellung überall auf diesem Planeten.

Leider ist SQL Server eher schwach Handhabungstermine - vielleicht könnte das ein Erweiterungspunkt sein, wo die Verwendung einer CLR-Assembly in SQL Server Sinn machen würde, um die viel reicheren Datumshandhabungsfunktionen in .NET anzuzapfen.

Marc

PS: scheint das ISO-8601-Format Ich wusste, YYYY-MM-DD immer in SQL Server nicht funktioniert - im Gegensatz zu dem, was Büchern Online scheinen zu predigen. Verwenden Sie stattdessen YYYYMMDD oder YYYY-MM-DDTHH: MM: SS.
Danke, gnn!

+0

Dies ist ANSI nicht ISO. ISO wäre '1998-02-23T14: 23: 05' – gbn

+0

... ohne "T" und Zeit, JJJJ-MM-TT ist standardmäßig auf ANSI – gbn

+0

Mein System befindet sich in einer kontrollierten Umgebung, es wird kein deutsch-schweizerisches Datum geben Konvertierungsprobleme. Ich mag die Try-Catch-Idee.Ich werde wahrscheinlich die IF ISDATE() und @Temp entfernen, und dann nur die Konvertierung Fehler wenn SET SET @ Ziel = LINKS (@ Source, 2) + '/' + SUBSTRING (@ Source, 3,2) + '/' + RECHTS (@ Source, 4) –

6

Sie können die Datum-Monat-Jahr-Reihenfolge mit SET DATEFORMAT garantieren. Dies bedeutet ISDATE wird '15 -07-2009 'als 15. Juli 2009

analysieren Andernfalls ist Ihr Ansatz angesichts der externen Einschränkungen gut genug ... aber Sie könnten auch in ANSI/ISO neu anordnen.

Nach marc_s' Antwort: "SET DATEFORMAT dmy" für die meisten europäischen Einstellungen funktioniert ...

OK:

SET LANGUAGE british 
SELECT ISDATE('2009-07-15') --this is ansi says marc_s. It gives "zero" 
SELECT ISDATE('2009-07-15T11:22:33') --this really is ANSI and gives true 


SET LANGUAGE german 
SELECT ISDATE('2009-07-15') --false 
SELECT ISDATE('2009-07-15T11:22:33') --true 
+0

vereinbart - für die meisten - aber warum nicht das ISO-8601-Format verwenden, das für alle Einstellungen von SET DATEFORMAT funktioniert? Einfach auf Nummer Sicher gehen ... –

+0

ISO-8601 funktioniert für alle Einstellungen, aber es ist nicht ISO: es ist ANSI, die Sie angegeben haben http://StackOverflow.com/Questions/1135746/SQL-Server-Convert-String-to- datetime – gbn

+0

MS Books Online scheint nicht zu stimmen: http://msdn.microsoft.com/en-us/library/ms190977%28SQL.90%29.aspx –

Verwandte Themen