【问题标题】:How to use LIKE in dynamic SQL in a stored procedure?如何在存储过程的动态 SQL 中使用 LIKE?
【发布时间】:2016-07-15 02:21:31
【问题描述】:

我使用动态 SQL 编写了一个存储过程:

create procedure [dbo].[SearchProduct]
    (@ProductId int = null, @ProductName nvarchar(50) = null)
as
    declare @SqlStr nvarchar(max)
    declare @ParaList nvarchar(2000)

    set @SqlStr = 'select p.* from dbo.Product where (1=1) '

    if @ProductName is not null
       set @SqlStr = @SqlStr + 'and(p.ProductName like '''%' + @ProductName2+'%''')'

    set @ParaList='@ProductId2 int , @ProductName2 nvarchar(50)'

    EXECUTE SP_EXECUTESQL @SqlStr,@ParaList,@ProductId,@ProductName

但我得到一个错误:

“Like operator”错误:数据类型 varchar 和 varchar 在模运算符中不兼容。

如果我改变:

set @SqlStr = @SqlStr + 'and(p.ProductName like ''%' + @ProductName2+'%'')'

我明白了:

@ProductName2 不声明。

【问题讨论】:

    标签: sql sql-server stored-procedures dynamic-sql


    【解决方案1】:

    由于您对此很陌生,请接受我的这些注释:

    1. 至于您的问题...您的选择语句以where 结尾,然后您以and 结尾

    select p.* from dbo.Product where '

    % 之前,你应该只有2 个单引号而不是3.. Like ' '%' +.... + '%' '...

    1. 当您执行动态 sql 过程时,始终首先使用 print() 方法而不是 exec 来评估您的 sql。

    2. 使用case when 语句而不是if statements. 它将更好地组织您的代码。

    3. 由于动态 sql 确实是非常糟糕的做法...您的问题应该是“如何将此过程转换为普通 sql 而不是动态...”

    最后,请接受我对缺少示例、错误和帮助链接的歉意,因为我是通过手机回答的。

    【讨论】:

    • 感谢您的建议,@Sufyan。 1> 我修好了。如果我有 2 个单引号:错误(必须声明 @ProductName2)。 2> 和 3> 我跟着你做。 4> 动态sql不好,但我想搜索多值和优化算法:使用动态sql。
    • @Mr.Ken 最坏的情况是通过 sp_executesql 封装查询。您可以隐藏整个语句,并且可以明确规定如何读取和清理变量。
    • 我使用动态 sql 因为我需要在数据库中搜索多个值。你有另一种优化算法来解决这个问题吗? @clifton_h
    • @Mr.Ken 我的话可能有点鲁莽,一定要使用动态sql。只需使用 sp_executesql 或 sp_execute。 sp_executesql can be used instead of stored procedures to execute a Transact-SQL statement many times when the change in parameter values to the statement is the only variation. Because the Transact-SQL statement itself remains constant and only the parameter values change, the SQL Server query optimizer is likely to reuse the execution plan it generates for the first execution. MSDN SQL 注入是通过这种方式防止的
    • 那我应该使用动态 Sql 吗?
    【解决方案2】:

    你有一两句话太多了:

    if @ProductName is not null
        set @SqlSt r = @SqlStr + 'and (p.ProductName like ''%' + @ProductName2+'%'')';
    

    在一个字符串中,两个单引号代表字符串中的一个单引号。然后第三个单引号结束字符串。

    【讨论】:

    • 但我得到错误:必须声明标量变量“@ProductName2”。
    • @Mr.Ken 。 . .该变量用于您的原始问题。我不知道它是如何分配的。
    【解决方案3】:

    应该在下面。你把单引号弄错了

    if @ProductName is not null
         set @SqlStr=@SqlStr+'and(p.ProductName like ''% + @ProductName2 + %'')'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-16
      • 2015-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-10
      • 1970-01-01
      相关资源
      最近更新 更多