在存储过程中转换为日期时间时出错

时间:2018-04-20 05:25:25

标签: sql sql-server sql-server-2008

我收到的错误如下:

  

Msg 241,Level 16,State 1,Procedure spQueryMgt,Line 106 [Batch   开始第13行]转换日期和/或时间时转换失败   来自字符串。

ALTER PROCEDURE [dbo].[spQueryMgt]
    @Mode               varchar(50)='',
    @Query_Form         varchar(20)='',
    @Patient_ID         bigint=0,
    @Verified_By        bigint = 0,
    @Verified_Date      datetime=''
AS
BEGIN
IF(@mode='Post_Query')
BEGIN

DECLARE @sql NVARCHAR(MAX);

SET @sql = N'Update '+ CONVERT(varchar(12), @Query_Form) +' Set
        Verified_By='+CONVERT(VARCHAR(12), @Verified_By)+',
        Verified_Date='''+CONVERT(datetime, @Verified_Date,20)+'''
        where Patient_ID = '+CONVERT(varchar(12), @Patient_ID)

        EXEC sp_executeSQL @sql;

END
END

2 个答案:

答案 0 :(得分:1)

将您的查询更改为 -

SET @sql = N'Update '+ CONVERT(varchar(12), @Query_Form) +' Set
        Verified_By='+CONVERT(VARCHAR(12), @Verified_By)+',
        Verified_Date='''+CONVERT(VARCHAR(20), @Verified_Date,20)+'''
        where Patient_ID = '+CONVERT(varchar(12), @Patient_ID)

您的convert功能存在问题。您正在将@Verified_Date转换为datetime并将datetimevarchar字符串连接起来。

答案 1 :(得分:1)

问题在于您将datetime转换回datetime,然后尝试concatinate,它会为您提供异常。

但是,通过将参数初始化为'' 0,你正在用不需要的值填充你的数据库,比如''对于varchars而言,1900-01-01表示日期时间列,更糟糕的是0表示整数列 那是你真正想要的吗?我对此表示怀疑 无法确定某个字段是故意设置为此值还是留空并让您稍后陷入麻烦。

您可以像这样执行此过程以在空参数中获取NULL值

ALTER PROCEDURE [dbo].[spQueryMgt] (
  @Mode               varchar(50) = NULL,
  @Query_Form         varchar(20) = NULL,
  @Patient_ID         bigint = NULL,
  @Verified_By        bigint = NULL,
  @Verified_Date      datetime = NULL
)
AS
BEGIN
  SET NOCOUNT ON; 

  IF @mode ='Post_Query'
  BEGIN
     DECLARE @sql NVARCHAR(MAX);

     if (@Query_Form is not null) and (@Patient_ID is not null) -- nu use in updating when no table or id is given
     begin
         SET @sql = N' Update ' + CONVERT(varchar(12), @Query_Form) +
                     ' Set Verified_By = ' + isnull(CONVERT(VARCHAR(12), @Verified_By), 'null') + ',' +
                     ' Verified_Date = ' + case when @Verified_Date is null then 'null' else '''' + CONVERT(varchar(20), @Verified_Date, 20) + '''' end + 
                     ' where Patient_ID = ' + isnull(CONVERT(varchar(12), @Patient_ID), 'null')

         EXEC sp_executeSQL @sql;
     end
  END
END

EDIT
正如评论中所提到的,你也应该注意sql注入,这样可以使你的程序更安全,但也更容易

create PROCEDURE [dbo].[spQueryMgt] (
  @Mode               varchar(50) = NULL,
  @Query_Form         varchar(20) = NULL,
  @Patient_ID         bigint = NULL,
  @Verified_By        bigint = NULL,
  @Verified_Date      datetime = NULL
)
AS
BEGIN
  SET NOCOUNT ON 

  IF @mode = 'Post_Query'
  BEGIN
     DECLARE @sql NVARCHAR(MAX)

     if (@Query_Form is not null) and (@Patient_ID is not null) -- nu use in updating when no table or id is given
     begin
         SET @sql = N'Update @P0 ' + 
                     'set Verified_By = @P1, ' + 
                     '    Verified_Date = @P2 ' + 
                     'where Patient_ID = @P3'

         EXEC sp_executesql @sql, 
              N'@P0 varchar(20), @P1 bigint, @P2 bigint, @P3 datetime', 
              N'@P0 = @Query_Form, @P1 = @Verified_By, @P2 = @Verified_Date, @P3 = @Patient_ID'
     end
  END
END