Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 转换和验证日期字符串的最佳方法_Sql Server_Sql Server 2005_Tsql - Fatal编程技术网

Sql server 转换和验证日期字符串的最佳方法

Sql server 转换和验证日期字符串的最佳方法,sql-server,sql-server-2005,tsql,Sql Server,Sql Server 2005,Tsql,我在存储过程中有一个格式为ddmmyyyy的char(8)变量(该值的质量和有效性未知,超出我的控制范围)。将值移动到datetime变量中并在datetime无效时抛出错误的最佳方法是什么 DECLARE @Source char(8) DECLARE @Destination datetime SET @Source='07152009' --your solution here SELECT @Destination 以下是我能想到的最好的方法: DECLARE @

我在存储过程中有一个格式为ddmmyyyy的char(8)变量(该值的质量和有效性未知,超出我的控制范围)。将值移动到datetime变量中并在datetime无效时抛出错误的最佳方法是什么

DECLARE @Source       char(8)
DECLARE @Destination  datetime

SET @Source='07152009'

--your solution here


SELECT @Destination
以下是我能想到的最好的方法:

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 @Destination=@Temp

SELECT @Source AS Source, @Temp AS  Temp, @Destination AS Destination
编辑以下是我要介绍的内容

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

首先,由于您使用的是SQL Server 2005,因此应该将可能失败的代码放入T-SQL的
BEGIN-TRY…..END-TRY-BEGIN-CATCH…..END-CATCH
blocks-TRY/CATCH blocks

第二,对于所有的日期操作,无论SQL Server中设置了什么样的当前日期格式,我都会使用它

ISO-8601格式是
yyyyymmdd
仅用于日期,或
YYYY-MM-DDTHH:MM:SS
用于带时间的日期-因此我将您的代码编写为:

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
不要依赖于正在设置的任何特定日期格式!!把你的代码发给我,我会在瑞士-德国的系统上试用——我几乎可以保证,如果你盲目地假设“en-US”和“mm/dd/yyyy”,它会崩溃——在这个星球上的任何地方都不是相同的设置

不幸的是,SQL Server处理日期的能力相当弱-这可能是一个扩展点,在SQL Server中使用CLR程序集可以利用.NET中更丰富的日期处理功能

马克

PS:似乎我知道的YYYY-MM-DD的ISO-8601格式在SQL Server中并不总是有效-这与在线书籍所宣扬的相反。改用YYYYMMDD或YYYY-MM-DDTHH:MM:SS。

谢谢,gbn

您可以使用SET-DATEFORMAT保证日期-月-年订单。 这意味着ISDATE将把“15-07-2009”解析为2009年7月15日

否则,考虑到外部限制,您的方法已经足够好了。。。但您也可以重新排序为ANSI/ISO

在marc_的回答之后:“SET DATEFORMAT dmy”适用于大多数欧洲设置

好:


对我来说似乎不错,我也会这么写的。我很想知道是否有更好的。大多数人都同意,但为什么不使用ISO-8601格式,它适用于SET DATEFORMAT的所有设置??请注意安全……ISO-8601适用于所有设置,但它不是ISO:它是ANSI,您指定的MS联机丛书似乎不同意:确实如此。但yyyy-mm-dd不是ISO。yyyy-mm-ddThh:mm:ss[.mmm]是ISO,正如您的链接所示。如果没有时间,它默认为ANSI.interest-SQL联机丛书和SQL Server中的实际实现不匹配。。。。。隐马尔可夫模型。。。。我第一次看到这个!这是ANSI而不是ISO。ISO将是“1998-02-23T14:23:05”…如果没有“T”和时间,yyyy-mm-dd默认为ANSIMy系统处于受控环境中,则不会出现瑞士-德国日期转换问题。我确实喜欢尝试捕捉的想法。我很可能会删除IF ISDATE()和@Temp,然后在执行SET@Destination=LEFT(@Source,2)+'/'+子字符串(@Source,3,2)+'/'+RIGHT(@Source,4)时捕获转换错误(如果有),上面编码的版本在我的系统上不起作用,RAISERROR()将被命中以获取有效日期@Temp='20091507',ISDATE='20091507')=1操作对不起-混淆了日期和月份-修复了我的代码块-现在对我有效
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