T-SQL过程不工作,varchar到日期转换出现问题

T-SQL过程不工作,varchar到日期转换出现问题,sql,sql-server,date,sql-server-2012,date-parsing,Sql,Sql Server,Date,Sql Server 2012,Date Parsing,运行此SP时,我得到: Msg 241,16级,状态1,程序PED_SP_PED_更新,第22行 从字符串转换日期和/或时间时,转换失败 执行情况如下: exec dbo.ped_sp_ped_updates @CURRENTHICN='111111111A', @DATERECEIVED = '20140904', @FIELDTOBECHANGED='FIRST_NAME_MEMBER', @CURRENTFIELDVALUE = 'MARY', @NEWFIELDVALUE = 'MARY

运行此SP时,我得到:
Msg 241,16级,状态1,程序PED_SP_PED_更新,第22行 从字符串转换日期和/或时间时,转换失败

执行情况如下:

exec dbo.ped_sp_ped_updates
@CURRENTHICN='111111111A',
@DATERECEIVED = '20140904',
@FIELDTOBECHANGED='FIRST_NAME_MEMBER',
@CURRENTFIELDVALUE = 'MARY',
@NEWFIELDVALUE = 'MARYTEST',
@REQUESTEDBY = 'IPISORS',
@ID=156
我不知道为什么,我将把varchar放回一个日期进行比较。
请注意,告诉我一个更好的方法是没有问题的,但是(我认为)如果我能够,至少“还”得到一个关于我当前程序不起作用的直接答案,那将对我的学习更有帮助。除了关于为什么要做得不同、更好等的有用想法之外

ALTER PROCEDURE [dbo].[PED_SP_PED_Updates]
    @CurrentHicn VARCHAR(500),
    @DateReceived VARCHAR(20),
    @FieldToBeChanged VARCHAR(500),
    @CurrentFieldValue VARCHAR(500),
    @NewFieldValue VARCHAR (500),
    @RequestedBy VARCHAR(10),
    @ID int

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    DECLARE @CurrentDBNote VARCHAR(MAX)
    DECLARE @NewNote VARCHAR(MAX)
    DECLARE @CountofHicn INT

    SET @NEWNOTE = 'Isaac Pisors | ' + GetDate() + ' | ' 
            + 'Changing field: ' + @FieldToBeChanged + ' from ' + @CurrentFieldValue + ' to ' + @NewFieldValue
            + ', per ' + @RequestedBy + ' request.  Also changing any related DOCS/FAXES records to correspond'

    SET @CurrentDBNote=
        (SELECT NOTES_GENERAL FROM PED_APPLICATIONS WHERE HICN_MEDICARE_NUMBER=@CurrentHicn AND (Cast(ISNULL(DATE_RECEIVED,'1900-01-01') as DATE)=CAST(@DateReceived AS DATE)))

    --NOW ADD THE TWO:
    SET @NewNote = @CurrentDBNote + CHAR(13) + @CurrentDBNote

    --SEE IF THERE IS STILL A MATCHING RECORD
    SET @CountofHicn=
        (SELECT COUNT(*) FROM PED_APPLICATIONS WHERE HICN_MEDICARE_NUMBER=@CurrentHicn AND (CAST(ISNULL(DATE_RECEIVED,'1900-01-01') AS DATE)=CAST(@DateReceived AS DATE)))

    IF @CountofHicn=0  --THERE IS NO LONGER A MATCHING RECORD - INSERT THAT NOTE AND CALL IT A DAY
        BEGIN   
            UPDATE PED_PEDUPDATES SET COMPLETEDON=GetDate(), COMPLETEDBY='SSIS',
            EXCEPTIONNOTE='Could not locate any records where HICN is ' + @CurrentHicn + ' and Date Received is ' + CAST(@DateReceived AS VARCHAR)
            WHERE [ID]=@ID
        END
    ELSE                --GO AHEAD AND DO THE UPDATE
        BEGIN
            UPDATE PED_APPLICATIONS SET @FieldToBeChanged = @NewFieldValue
            WHERE HICN_MEDICARE_NUMBER=@CurrentHicn AND (CAST(ISNULL(DATE_RECEIVED,'1900-01-01') AS DATE)=CAST(@DateReceived AS DATE))
        END

    IF @FieldToBeChanged='HICN_MEDICARE_NUMBER' --THEN WE HAVE TO UPDATE DOCS TABLE, TOO
        BEGIN
            UPDATE PED_DOCS SET HICN_MEDICARE_NUMBER=@NewFieldValue
            WHERE
                (HICN_MEDICARE_NUMBER=@CurrentFieldValue AND (CAST(ISNULL(DATE_RECEIVED,'1900-01-01') AS DATE)=@DateReceived)) or
                (HICN_MEDICARE_NUMBER=@CurrentFieldValue AND DATE_RECEIVED IS NULL)
        END

    IF @FieldToBeChanged='HICN_MEDICARE_NUMBER'     --THEN OUR WHERE CLAUSE-HICN IS THE *NEW* HICN
        BEGIN
            UPDATE PED_APPLICATIONS SET NOTES_GENERAL=@NewNote
            WHERE HICN_MEDICARE_NUMBER=@NewFieldValue AND (CAST(ISNULL(DATE_RECEIVED,'1900-01-01') AS DATE)=CAST(@DateReceived AS DATE))
        END
    ELSE                                            --ELSE OUR WHERE CLAUSE-HICN IS THE *OLD* HICN
        BEGIN
            UPDATE PED_APPLICATIONS SET NOTES_GENERAL=@NewNote
            WHERE HICN_MEDICARE_NUMBER=@CurrentHicn AND (CAST(ISNULL(DATE_RECEIVED,'1900-01-01') AS DATE)=CAST(@DateReceived AS DATE))
        END

    --FINALLY, UPDATE RECORD AS COMPLETE:
    UPDATE PED_PEDUPDATES SET COMPLETEDON=GetDate(),COMPLETEDBY='SSIS' WHERE [ID]=@ID


END


GO

短期修复

  • 使用
    转换(日期,@DateReceived,112)

    值112是您正在使用的格式化varchar的样式代码。有关更多详细信息,请参阅

  • 此外,您还应验证表的
    DATE\u RECEIVED
    列中的所有值的格式是否正确。即使一个不可转换的值也会导致此错误

正确修复

  • @DateReceived
    应作为
    date
    而不是
    varchar
    传递到过程中

  • 表中的
    DATE\u RECEIVED
    字段应声明为
    DATE
    ,而不是
    varchar


一般来说,如果数据库中有用于此目的的本机类型,请避免将日期或时间视为字符串。

在这个回答中,我假设您使用的是Microsoft SQL Server,而不是其他SQL变体,如MySQL。如果没有,请让我知道,并适当地标记您的问题。每当我尝试标记某些内容时,超光滑的文本编辑器太光滑了,不利于自己!我不能不把它转换成别的东西就打字。每当我有一个空格或连字符时,它通常表示我不想要的东西,所以我不确定。让我再试一次,很抱歉造成混乱。下一次我会更加小心。前几天我在网上读了我的第一篇关于SQL Server日期/日期格式等的文章。有一个夸张的说法,比如:“如果您总是使用YYYYMMDD作为字符串到日期转换的起点,那么无论本地设置如何,您都不会出错,因为这是ISO标准”。也许我太在意那句话了,或者?ISO格式在许多情况下都可以工作,但如果不小心,也可能会受到本地计算机设置的影响。最好的建议是不要在SQL中处理字符串到日期的转换。这在应用程序代码中得到了最好的处理。这完全有道理-谢谢。我可以再问一个问题吗?当我运行这个SQL:SELECT CAST('20140904'作为日期)时,它似乎在SSMS的结果窗口中作为日期类型返回。这就是为什么我认为我对传入值('20140904')的选择不可能是个问题。