使用存储过程搜索表数据的首选方法是什么?

时间:2012-04-09 12:30:47

标签: sql sql-server sql-server-2008 tsql search

我有customerCust_IdNameCity,搜索基于以上三种中的任何一种或全部。

我应该去哪一个?

  1. 动态SQL:

    declare @str varchar(1000)
    set @str = 'Select [Sno],[Cust_Id],[Name],[City],[Country],[State] 
                from Customer where 1 = 1'
    if (@Cust_Id != '')
        set @str = @str + ' and Cust_Id    =  ''' + @Cust_Id + ''''
    if (@Name != '')
        set @str = @str + ' and Name like ''' + @Name + '%'''
    if (@City  != '')
        set @str = @str + ' and City like ''' + @City + '%'''
    exec (@str)
    
  2. 简单查询:

    select
        [Sno],[Cust_Id],[Name],[City],[Country],[State]
    from
        Customer
    where
        (@Cust_Id  = '' or Cust_Id    =  @Cust_Id) and
        (@Name     = '' or Name     like @Name + '%') and
        (@City     = '' or City     like @City + '%')
    
  3. 我应该选择哪一个(1或2)以及有什么优势?

    经过大家的建议后,这就是我最终得到的。

      DECLARE @str NVARCHAR(1000)
      DECLARE @ParametersDefinition NVARCHAR(500)
      SET @ParametersDefinition = N'@InnerCust_Id varchar(10),
                                  @InnerName varchar(30),@InnerCity varchar(30)'
    
    
     SET @str = 'Select [Sno],[Cust_Id],[Name],[City],[Country],[State]
                                              from Customer where 1 = 1'
    
     IF(@Cust_Id != '')
        SET @str = @str + ' and Cust_Id = @InnerCust_Id'
     IF(@Name != '')
        SET @str = @str + ' and Name like @InnerName'
     IF(@City  != '')
        SET @str = @str + ' and City like @InnerCity'
    
    
    -- ADD the % symbol for search based upon the LIKE keyword
    SELECT  @Name = @Name + '%', @City = @City+ '%'
    
    EXEC sp_executesql @str, @ParametersDefinition,
                          @InnerCust_Id = @Cust_Id,
                          @InnerName    = @Name,
                          @InnerCity    = @City;
    

    注意@Cust_Id@Name@City是传递给存储过程的参数

    参考文献:   http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/changing-exec-to-sp_executesql-doesn-t-p

    http://www.sommarskog.se/dynamic_sql.html

    http://msdn.microsoft.com/en-us/library/ms175170.aspx

3 个答案:

答案 0 :(得分:4)

动态SQL编写起来有点困难,如果不小心,它很容易受到SQL注入攻击。但是,它优于“非动态”/简单或查询。

在这里阅读更多相关信息。 http://blogs.lessthandot.com/index.php/DataMgmt/DBProgramming/do-you-use-column-param-or-param-is-null

答案 1 :(得分:4)

动态SQL可能更具性能,这在搜索中通常很重要。

然而,编写,调试和测试更加困难。首先,您需要确保它不允许SQL注入攻击。接下来,您需要确保您使用的变量足够大,以包含您将创建的最大可能的最终SQl语句。

然后你需要创建大量的测试用例,以确保没有某种微妙的bug。

您还需要向基础表授予读取权限,如果使用存储过程,通常不需要这样做。

最后,当在存储过程中执行动态SQL时,请添加一个名为@debug的输入变量作为最后一个输入变量,并给它一个默认值0.当传入1时,而不是执行动态SQL,它将向您发送创建的SQL。这将帮助您调试proc,并且在将来某些搜索中出现错误时尤其有用,因为您可以确切地看到为这些值运行的SQL。

答案 2 :(得分:1)

根据我的经验,动态SQL只有减少JOIN数量才有意义(获得性能)。

否则只会恶化代码的可读性和可维护性。