2015-07-28 17 views
2
DECLARE @id int 
DECLARE @name nvarchar(20) 
SET @id = 5 
SET @name = 'Paul' 

使用@ParmDefinition的優點是什麼這兩個選項之間的區別:什麼是sp_executesql的

Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = ' + @id + ' AND NAME = ''' + @name + '''' 
Execute sp_Executesql @SQLQueryInnen 

Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = @id AND NAME = @name' 
Set @ParmDefinition = '@id int, @name nvarchar(20)' 
Execute sp_Executesql @SQLQueryInnen, @ParmDefinition, @id 

到目前爲止,我只看到了overhad的聲明使用@ParmDefinition時@id和@name的數據類型兩次。另一方面,使用@ParamDefinition,「字符串構建」似乎更容易一些。

+4

第二一個參數化您的查詢,這有助於防止SQL注入。 –

回答

3

您避免stringly -typed代碼 - 你必須一切轉換爲字符串,這樣就可以推入@SQLQueryInnen參數,然後介紹問題,因爲你必須解決如何安全地,毫不含糊地執行將字符串之間的轉換轉換回正確的原始數據類型。

對於int s,轉換問題不是很明顯。但是,如果你看看人們在datetime和字符串之間轉換的問題(在這裏和其他論壇上)的問題數量,你會發現它確實會導致真正的問題。最好始終保持數據的自然類型。

2

第一種情況是SQL注入容易和安全風險。討論在這裏停止。

+0

ja,我之前聽說過這個詞,但從未真正試圖理解它的含義,現在我可以看到它在第一種情況下會有多危險...... – Kiechlus

1

我看到沒有人提到最重要的事情之一。當你使用參數化查詢時,你的執行計劃被緩存。

您的查詢,這就是:

SELECT * 
FROM someTable 
WHERE ID = @id 
    AND NAME = @name; 

其執行計劃將被存儲IM內存,它會在您每次查詢它(這是一個很大的好處)時重複使用。同時,如果您生成使用字符串連接這樣的代碼:

Set @SQLQueryInnen = 'SELECT * FROM someTable WHERE ID = ' + @id + ' AND NAME = ''' + @name + '''' 
Execute sp_Executesql @SQLQueryInnen 

您的代碼將生成每個參數組合執行計劃(除非重複)和緩存計劃不會被重用。試想一下,你傳遞@Id = 1@Name = 'Paul',您提出的疑問會是這樣的:

SELECT * 
FROM someTable 
WHERE ID = 5 
    AND NAME = 'Paul'; 

如果你改變你的名字'Rob',您提出的疑問會像和SQL Server將創建一個新的計劃,它:

SELECT * 
FROM someTable 
WHERE ID = 5 
    AND NAME = 'Rob'; 

含義計劃將不會被重複使用。希望能幫助到你。

這是一篇文章詳細解釋了這一點:EXEC vs. sp_executeSQL(不要依賴文章標題,它解釋了你問你的問題的確切區別)。從中報價:

的TSQL字符串是建立只有一次,每一次相同 查詢調用sp_executesql的後,SQL Server在高速緩存中檢索查詢 計劃,並重新使用它