2009-01-20 23 views
3

如果我以這種格式編寫一個sproc,sql server會有效地執行這個操作還是應該在服務器端(.net)完成sql'編織'?這是一個高效的sql服務器查詢?

注:這是什麼我的查詢看起來像只是一個粗略的想法,有更多的「如果」子句建立我查詢我執行使用「EXEC」

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 

回答

0

你有一個好做這個動態SQL的原因是什麼?

我已經完成了你以前在SQL服務器上的工作,它工作正常;它可能更安全(取決於使用情況),而不是將完全形成的SQL傳遞給只是盲目運行的proc。

如果您使用SQL 2k5或2k8,則可以對更長的字符串使用nvarchar(max)。

-1

是的。

它編譯在「exec」命令中。在這之間速度差異應該是最小的,並且在.NET一邊做這一切。

在某個時間點,它將SQL編譯爲一些內部代碼。它可能發生在.NET推動它,或之後。

4

而不是建立一個SQL字符串,爲什麼不按順序使用case語句?

例如(假設是通過第一和/或姓氏與名字和姓氏字段的表排序)

order by 
    case 
    when @sortExpression = 'lastname asc' then CAST(LastName as sql_variant) 
    when @sortExpression = 'firstname asc' then CAST(FirstName as sql_variant) 
    end asc, 
    case 
    when @sortExpression = 'lastname desc' then CAST(LastName as sql_variant) 
    when @sortExpression = 'firstname desc' then CAST(FirstName as sql_variant) 
    end desc 

另外,如果您的ORDER BY子句通過動態SQL每一次不同的是,查詢計劃決不會重新使用。

+0

類型列必須是相同的(NULL未使用的): ORDER BY CASE WHEN @Order 1 THEN [ DateOfBirth] ELSE NULL END ,CASE @Order WHEN 2 THEN [DateOfBirth] ELSE NULL END DESC ,CASE @Order WHEN 3 THEN [LastName] ELSE NULL END ,CASE @Order WHEN 4 THEN [LastName] ELSE NULL END DESC – IDisposable 2009-01-26 21:32:58

+0

不,他們不。只要您將CAST轉換爲sql_variant,那麼這些列在同一CASE中都可以是不同的類型,並且不需要將任何值設置爲NULL。嘗試一下,它的作品。我做了很多次。 – 2009-01-27 16:09:56

+0

如果您轉換爲sql_variant,則排序邏輯將基於字符串,因此數值不會按預期排序。 – IDisposable 2009-06-24 19:25:56

-5

我會構建查詢的其餘部分直到由ie的順序。

@sql = 'SELECT id, name FROM myTable ORDER BY ' + @order 

...並將列名和方向傳遞給proc。這種方式更安全,因爲沒有太多的事情可以傳遞給訂單旁邊的條款造成任何傷害。

要回答你的問題,是的,它是有效的。

1

我看到兩個更好的方法來做到這一點。相反,使用動態SQL查詢的,我會用在存儲過程中的實際的SQL語句,用你想訂購的東西套管由:

select 
    t.* 
from 
    table as t 
order by 
    case @val 
    when 1 then column1 
    when 2 then column2 
    end 

如果您發現由訂單過於動態的,必須是建起來了,或者是easer這樣做,那麼我將創建一個表值函數返回集合,然後創建針對動態SQL語句:

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

這裏當然,t.col1,T .col2等等,都是在將整個事件發送到服務器之前動態生成的。

2

最清晰,最簡單,最簡單,最優化的方式是爲每個選項提供完整的SQL語句。

0

要專門回答你的問題,你的.Net層中形成的動態SQL語句與proc中形成的完全相同的SQL字符串之間完全沒有性能差異。

0

最有效的方法是從數據庫中獲取所需的任何數據,然後在應用程序中處理排序。更改順序不會改變數據量。如果用戶更改排序順序,爲什麼要再次訪問數據庫?

0

動態查詢性能幾乎等同於服務器端編織。如果您找不到任何其他方式來避免動態查詢,請將其嵌套在服務器端。

下也能在情況下,你沒有太多的 「如果」

if(@sortorder = 'name') select id, name from tbl order by name asc 
if(@sortorder = 'id') select id, name from tbl order by id asc