Sql server 这是一个高效的sql server查询吗?

Sql server 这是一个高效的sql server查询吗?,sql-server,performance,tsql,Sql Server,Performance,Tsql,如果我以这种格式编写存储过程,sql server是否会有效地执行此操作,还是应该在服务器端(.net)上执行sql“编织” 注意:这只是我的查询的大致情况,在我使用“exec”执行的构建我的查询时,有更多的“if”子句 declare @sql nvarchar(4000) declare @order nvarchar(4000) set @sql = 'select id, name' set @sql = @sql + ' ....' if(@sortOrder) set

如果我以这种格式编写存储过程,sql server是否会有效地执行此操作,还是应该在服务器端(.net)上执行sql“编织”

注意:这只是我的查询的大致情况,在我使用“exec”执行的构建我的查询时,有更多的“if”子句

declare @sql nvarchar(4000)
declare @order nvarchar(4000)


set @sql = 'select id, name'
set @sql = @sql + ' ....' 

if(@sortOrder)
    set @order = 'order by name desc'

exec @sql + @order

作为动态SQL,您有充分的理由这样做吗

我已经在SQL server中完成了您之前所做的工作,并且工作正常;它可能比将完全格式的SQL传递给盲目运行的进程更安全(取决于使用情况)

如果您使用的是SQL 2k5或2k8,则可以使用nvarchar(最大值)处理更长的字符串。

它在“exec”命令中编译。在这两者之间的速度差异应该是最小的,并且在.NET端完成这一切


在某些时候,它会将SQL编译成一些内部代码。它可以在.NET推送它时发生,也可以在推送之后发生。

与其构建SQL字符串,为什么不按顺序使用case语句呢

e、 g.(假设在具有FirstName和LastName字段的表上按名字和/或姓氏排序)


此外,如果您的order by子句通过动态SQL每次都不同,则查询计划将永远不会被重复使用。

我将根据ie构建order by查询的其余部分

@sql = 'SELECT id, name FROM myTable ORDER BY ' + @order
。。。并将列名和方向传递给进程。这种方法更安全,因为传递给order by子句造成任何伤害的内容不多


回答你的问题,是的,它是有效的。

我认为有两种更好的方法。我不使用动态SQL查询,而是在存储过程中使用实际的SQL语句,按您要排序的内容进行排序:

select
  t.* 
from 
  table as t 
order by
  case @val
    when 1 then column1
    when 2 then column2
  end
如果您发现order by过于动态,必须建立,或者更容易建立,那么我将创建一个返回集合的表值函数,然后针对该函数创建一个动态sql语句:

select
  t.*
from
  xfn_Function(@arg1, @arg2) as t
order by
  t.col1, t.col2

当然,t.col1、t.col2等都是在您将整个内容发送到服务器之前动态生成的。

最清晰、最简单、最容易、最优化的方法是为每个选项提供完整的SQL语句。

为了具体回答您的问题,在.Net层中形成的动态SQL语句与在进程中形成的完全相同的SQL字符串之间不会有任何性能差异。

最有效的方法是从数据库中获取所需的任何数据,然后在应用程序中处理排序。通过更改订单不会更改数据量。如果用户更改了排序顺序,为什么还要再次访问数据库?

动态查询性能几乎等同于服务器端编织。若您无法找到任何其他方法来避免动态查询,请将其嵌套在服务器端

如果你没有太多的“如果”,下面的方法同样有效


>>因为没有多少可以传递给order by条款造成任何伤害。哇,这只是wowBad的想法,但是,或者,您可以将order by作为整数传递,然后根据该整数的值,按与这些整数值对应的预定义列列表排序。我可以按“name;DROP TABLE myTable”对表进行排序吗“这种方法更安全,因为传递给order by子句的内容不会造成任何伤害。”语句。;update employee set salary=0,其中employee='ORTORD0KS';--我希望你们都在输入级别检查注入攻击。列的类型必须相同(未使用的列为NULL):order by CASE@order WHEN 1,然后[DateOfBirth]ELSE NULL END,CASE@Order WHEN 2然后[DateOfBirth]ELSE NULL END DESC,CASE@Order WHEN 3然后[LastName]ELSE NULL END,CASE@Order WHEN 4然后[LastName]ELSE NULL END DESCNo不是。只要强制转换为sql\U variant,在同一情况下,所有列都可以是不同类型的,您不需要将任何内容设置为NULL。试试看,它可以工作。我已经做过很多次了。如果强制转换为sql\U variant,排序逻辑将基于字符串,因此数值将不会按预期排序。
select
  t.*
from
  xfn_Function(@arg1, @arg2) as t
order by
  t.col1, t.col2
if(@sortorder = 'name') select id, name from tbl order by name asc
if(@sortorder = 'id') select id, name from tbl order by id asc