【问题标题】:Conversion failed when converting date from character string in a stored procedure从存储过程中的字符串转换日期时转换失败
【发布时间】:2021-05-26 19:42:08
【问题描述】:

我在运行带有日期参数的存储过程时遇到了问题。我在一个存储过程中有 2 个参数,它从表中返回一个结果集。在表中name 是nvarchar 类型,dateclient 是date。

参数的值来自用户界面。

ALTER PROCEDURE [dbo].[NAME_SEARCH] 
    @name nvarchar(255),
    @dateclient datetime
AS 
BEGIN 
    DECLARE @parsed_string nvarchar(max)

    EXEC parsing_coi_input @name, @parsed_string OUTPUT

    PRINT @parsed_string

    SET @name = @parsed_string

    DECLARE 
        @BaseQuery nvarchar(max) = 'SELECT Id, name, date_client
                                    FROM Client
                                    INNER JOIN CONTAINSTABLE (Client, ame,'''+ @name + ''') as name_key ON ID = name_key.[KEY]'
   DECLARE 
        @OrderByQuery nvarchar(max) = ' ORDER BY name_key.RANK'
   DECLARE
        @OrderDesc nvarchar(max) =' DESC'

   BEGIN 
       SET NOCOUNT ON;
       SET @BaseQuery = @BaseQuery + ' 
   INNER JOIN CONTAINSTABLE(Client, date_client,'''+ @dateclient  +''') AS 
   date_clientkey ON ID = date_clientkey.[KEY] WHERE date_client_matter_open >= '+ @dateclientmatter  
    +''
   SET @OrderByQuery = @OrderByQuery + ',date_client_key.RANK'

   END 

    DECLARE @fullQuery nvarchar(max)= @BaseQuery + @OrderByQuery + @OrderDesc
    EXECUTE sp_executesql @fullQuery
    END

我正在执行:

EXEC [dbo].[NAME_SEARCH] 'MGeolo','2009-04-05'

但我收到此错误:

从字符串转换日期和/或时间时转换失败。

任何建议如何处理?

【问题讨论】:

  • 你应该得到的是一个错误,因为你指定了太多参数,因为你的 sproc 定义只有两个参数并且你传递了 5。仔细检查你'正在寻找正确的东西。剩下的就是等待发生的 SQL 注入;你必须在这里动态,因为CONTAINSTABLE 不支持参数,但是当你必须做这样的事情时,一定要正确地转义字符串(用双撇号替换单撇号)。最后但并非最不重要的始终PRINT 执行前动态 SQL 的结果,因此您可以检查发生了什么。
  • Procedure dbo.NameSearch 创建动态 sql。你能提供生成的sql吗?例如,似乎是由 dbo.NameSearch 调用的自定义 proc。通常,您发布的错误表明 SQL Server 正在将您的输入与存在无法转换为日期时间的值的 varchar 列进行比较。
  • + CAST(@dateclient AS nvarchar(20)) + 也许?虽然不清楚您是否真的想搜索 datetime 的列,但我认为这是不可能的
  • + CAST(@dateclient AS nvarchar(20)) + 我已经尝试过了,但没有成功
  • 警告:您的代码很容易注入攻击。切勿在 SQL 中注入未经处理的字符串。

标签: sql sql-server tsql stored-procedures


【解决方案1】:

生成 SQL 脚本时缺少日期周围的 ' 字符以及从 datetime 到 varchar 的转换。

你应该这样做:

BEGIN 
       SET NOCOUNT ON;
       SET @BaseQuery = @BaseQuery + ' 
   INNER JOIN CONTAINSTABLE(Client, date_client,'''+ cast(@dateclient as varchar(200))  +''') AS 
   date_clientkey ON ID = date_clientkey.[KEY] WHERE date_client_matter_open >= '''+ cast(@dateclientmatter as varchar(200)) +''''
   SET @OrderByQuery = @OrderByQuery + ',date_client_key.RANK'

这可能是一个错字,但 @dateclientmatter 未声明,因为在标题中您只有 @dateclient。

【讨论】:

    猜你喜欢
    • 2015-05-22
    • 2017-11-06
    • 2019-10-20
    • 1970-01-01
    • 2013-03-13
    相关资源
    最近更新 更多