2013-06-24 73 views
0

我正在使用數據庫將部門名稱與其唯一的郵寄代碼相關聯,即Accounting具有郵寄代碼1337. ShortName和ID是正在查詢的數據庫的字段。SqlDataReader導致網頁無法加載

的架構是

  • ID int
  • ShortName nvarchar(255)

這是用C#網頁的後臺完成。我在同一代碼的其他地方使用了SqlDataReader對象,但沒有發生錯誤。我想我有一個語法錯誤的地方,或者我試圖將一個字符串粘到一個int或一些愚蠢的東西,但我看不到它。

SqlConnection設置正確,因爲它用於在加載頁面時進行查詢,並且在指示的行被註釋掉時工作。

SqlDataReader SQl_Reader; 
string cmdString = "SELECT ShortName FROM departments WHERE (ID = " + 
    department_Text.SelectedValue.ToString() + ")"; //a selected value in department_text would be the mailing code such as 1337, or 1304. 

SqlCommand SQl_Command2 = new SqlCommand(cmdString, SQl_Connection); 

SQl_Reader = SQl_Command.ExecuteReader(); 

string deptName = SQl_Reader["ShortName"].ToString();//This should assign the deptName = the value in SQl_Reader but it causes the page not to load. Not sure what is wrong with it 

SQl_Reader.Close(); 
SQl_Connection.Close(); 

我都試過,甚至採用了專有的連接,命令,和讀者只爲這本查詢多種不同的方式。我使用SqlDataReader作爲代碼的另一個函數中的相同的兩個字段的類似用途,它完美地工作。任何見解都將非常感激。

+2

你在這段代碼中有一個非常嚴重的sql注入漏洞。您需要使用參數化查詢。很可能「department_Text」的值不是您認爲的值,而且查詢也沒有返回任何結果,因此當您在空引用上調用「ToString()」時會引發異常。 – asawyer

+0

在讀取任何東西之前不應該調用SQL_Reader.Read()? –

回答

2

如果您要使用閱讀器,您需要在獲取值之前先致電Read()

如果您想要一個值,那麼最好使用ExecuteScalar()代替。

還可以使用參數化查詢,以防止SQL注入(和其他福利太)..

SqlDataReader SQl_Reader; 
    string cmdString = "SELECT ShortName FROM departments WHERE ID = @ID;" 
    SqlCommand SQl_Command2 = new SqlCommand(cmdString, SQl_Connection); 
    SQl_Command2.Parameters.Add("@ID", department_Text.SelectedValue); 
    SQl_Reader = SQl_Command.ExecuteReader(); 
    SQl_Reader.Read(); 
    string deptName = SQl_Reader["ShortName"].ToString(); 

    SQl_Reader.Close(); 
    SQl_Connection.Close(); 

或破越好..

SqlDataReader SQl_Reader; 
    string cmdString = "SELECT ShortName FROM departments WHERE ID = @ID;" 
    SqlCommand SQl_Command2 = new SqlCommand(cmdString, SQl_Connection); 
    SQl_Command2.Parameters.Add("@ID", department_Text.SelectedValue); 
    SQl_Reader = SQl_Command.ExecuteReader(); 
    SQl_Reader.Read(); 
    string deptName = SQl_Command.ExecuteScalar() as String; 

    SQl_Reader.Close(); 
    SQl_Connection.Close(); 
2

您從SQl_Reader需要.Read()在它將有任何數據之前。 通常你會做

While (SQl_Reader.Read()) 
{ 
    // Get values here 
} 

如果你一定只會有一個返回行,那麼你應該查詢更改爲

Select top 1 ShortName FROM 

但你仍然需要閱讀()。另外我同意關於面對注射攻擊的評論。你需要通過department_Text.SelectedValue作爲查詢參數

1

我假定ID是主鍵,所以沒有其他可能的specyfic ID值,那麼ExecuteScalar將完成這項工作。

string cmdString = "SELECT ShortName FROM departments WHERE (ID = @depId)"; 

using (SqlCommand SQl_Command2 = new SqlCommand(cmdString, SQl_Connection)) 
{ 
    //a selected value in department_text would be the mailing code such as 1337, or 1304. 
    SQl_Command2.Parameters.Add("@depId", System.Data.SqlDbType.Int).Value = department_Text.SelectedValue; 

    string deptName = (string)SQl_Command2.ExecuteScalar(); 
} 

不要忘記使用SqlCommand.Parameters Property而不是字符串連接。

我不擅自使用using自動處理對象,更多關於它:Is SqlCommand.Dispose() required if associated SqlConnection will be disposed?