2013-08-21 19 views
0

以下代碼據我瞭解應該創建一個參數化語句並向該參數添加一個值。參數爲「@exp」,添加的值由用戶輸入決定。我將用戶輸入存儲在String exp;(不是我選擇的其他人寫的這個函數的大部分)。當參數化查詢執行時,它似乎沒有參數的值

SQl_Command.CommandText = "SELECT COUNT(*) As MyCount FROM members WHERE ([Primary Exp] = '@exp') AND ([Approved] = 'True') OR ([Approved] = 'True') AND ([Secondary Exp] = '@exp')"; 
SQl_Command.Parameters.Add("@exp", SqlDbType.NVarChar, 255); 
SQl_Command.Parameters["@exp"].Value = exp; 

爲我的測試情況下,期望的結果是16,但此查詢返回0。從SQL Server 2008上運行時,查詢工作,看起來像這樣。

SELECT COUNT(*) As MyCount 
FROM members 
WHERE ([Primary Exp] = 'Risk Management') 
    AND ([Approved] = 'True') OR ([Approved] = 'True') 
    AND ([Secondary Exp] = 'Risk Management') 

我應該能夠使用Response.Write(SQl_Command.CommandText);,我選擇了「風險管理」和參數化查詢應該打印出來:

SELECT COUNT(*) As MyCount 
FROM members 
WHERE ([Primary Exp] = 'Risk Management') 
    AND ([Approved] = 'True') OR ([Approved] = 'True') 
    AND ([Secondary Exp] = 'Risk Management')` 

但是,由於它沒有。它離開@exp,就好像這是我想比較[Primary Exp]和[Secondary Exp] to的值。那是對的嗎?

我已經看到了這樣的多種方法,但我一般過以下的例子here

我不認爲這是問題,但是這是我如何使用查詢。

SQl_Reader = SQl_Command.ExecuteReader(); 
int numRows = 0; 
while(SQl_Reader.Read()){ 
    numRows = Convert.ToInt32(SQl_Reader["MyCount"]); 
} 

我敢肯定,這是一些簡單的我失蹤,但我沒有帶已經能夠看到它。

+1

你的期望是錯誤的 - 使用參數並不意味着客戶端的SQL代碼將**用這些參數替換它們的實際值。這些參數作爲參數**發送給SQL Server,包括它們在值列表中的值。這是它的方式和設計方式 - 如果您希望在將查詢發送到SQL Server之前將參數替換爲其實際值,那麼您就錯了。 –

回答

6

你在這裏處理變量,SQL對象不會簡單地執行「更安全」的搜索和替換。將您的代碼更改爲:

SQl_Command.CommandText = "SELECT COUNT(*) As MyCount FROM members WHERE 
     ([Primary Exp] = @exp) AND ([Approved] = 'True') OR 
     ([Approved] = 'True') AND ([Secondary Exp] = @exp)"; 

您應該找到您現在得到的正確值;與您的原始版本,它會逐字地搜索字符串'@exp'

請注意,SQL參數和命令本身僅在執行期間組合,作爲調用SQL Server的一部分。所以當你看到@exp仍然顯示在CommandText即使參數已被添加後,這實際上是正確的。

1

當您通過某個.NET SQL Server提供程序運行參數化查詢時,查詢會將其參數化爲所有到服務器的路徑。如果您在執行查詢時運行SQL Profiler,則會看到執行查詢的「RPC」事件,並沿途填入參數。

RPC是SQL客戶端通過名稱直接執行存儲過程的一種方式,而不是將T-SQL語句作爲文本執行。不是將您的SQL命令作爲T-SQL發送,而是以RPC調用的形式發送到「sp_executesql」,並將查詢和後續參數作爲參數發送給sp_executesql。所以,你的查詢將實際運行,就像這樣:

sp_executesql "SELECT COUNT(*) As MyCount FROM members WHERE ([Primary Exp] = '@exp') AND ([Approved] = 'True') OR ([Approved] = 'True') AND ([Secondary Exp] = '@exp')", "@exp NVARCHAR(255)", "@exp = 'Risk Management'" 

的區別進行了更詳細本文中介紹有關SQL Server Connection Basics.

相關問題