Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用存储过程搜索表数据的首选方法是什么?_Sql_Sql Server_Sql Server 2008_Tsql_Search - Fatal编程技术网

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

Sql 使用存储过程搜索表数据的首选方法是什么?,sql,sql-server,sql-server-2008,tsql,search,Sql,Sql Server,Sql Server 2008,Tsql,Search,我有一个Cust_Id、Name、City的customer表,搜索基于以上三者之一或全部 我该选哪一个 动态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、Name、City的customer表,搜索基于以上三者之一或全部

我该选哪一个

动态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)
简单查询:

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 + '%')
我应该选择1号还是2号?优点是什么

在仔细考虑了大家的建议后,我终于得到了这一点

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

参考资料:


根据我的经验,动态SQL只有在减少连接数量的情况下才能提高性能


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

根据我的经验,动态SQL只在减少连接数的情况下提高性能是有意义的


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

动态SQL可能会更难编写,如果不小心,它很容易受到SQL注入的攻击。但是,它的性能优于非动态/简单或查询


在这里阅读更多关于它的信息

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


在这里阅读更多关于它的信息

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

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

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

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


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

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

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

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

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


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

您的动态SQL版本易受SQL注入攻击。如果您决定采用这种方式,请使用sp_executesql和参数化查询。请参阅@MartinSmith,根据您的建议,我搜索并找到了一篇关于sp_executesql的使用情况超过EXEC以及它如何提高性能的文章,值得一读。这是@ALL的链接,根据大家的建议和引用的几个链接,我已经修改了搜索逻辑,但我不确定应该发布在哪里,我应该编辑问题并将逻辑附加到最后还是发布作为我问题的答案。您的动态SQL版本容易受到SQL注入的攻击。如果您决定采用这种方式,请使用sp_executesql和参数化查询。请参阅@MartinSmith,根据您的建议,我搜索并找到了一篇关于sp_executesql的使用情况超过EXEC以及它如何提高性能的文章,值得一读。这是@ALL的链接,每个人都有建议,参考了几个链接。我已经修改了搜索逻辑,但我不确定应该在哪里发布,我应该编辑问题并将逻辑附加到最后还是将其作为我问题的答案发布。不同意。通常至少有次优计划,除非选择重新编译used@Martin:同意。谢谢事实上,我说的是同一个案例,但不知道性能下降的实际原因。不同意。通常至少有次优计划,除非选择重新编译used@Martin:同意。谢谢实际上,我谈论的是同一个案例,但不知道性能受到影响的实际原因。simpe查询也可能容易受到参数嗅探问题的影响
E但肯定是一个更可读/更易于管理的解决方案。@G Mastros,谢谢你的链接,它对我真的很有帮助。@sam yi,sumple查询更可读,也更易于管理。但是G Mastros提供的链接说动态查询对性能有好处。@Mourya:是的,动态查询的性能更好。。。这就是我所说的参数嗅探次优计划问题。simpe查询也可能容易受到参数嗅探问题的影响。但肯定是一个更可读/更易于管理的解决方案。@G Mastros,谢谢你的链接,它对我真的很有帮助。@sam yi,sumple查询更可读,也更易于管理。但是G Mastros提供的链接说动态查询对性能有好处。@Mourya:是的,动态查询的性能更好。。。这就是我所说的参数嗅探次优计划问题。我将在我的过程中使用@debug变量,谢谢你的建议。我将在我的过程中使用@debug变量,谢谢你的建议。
  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;