[英]InvalidOperationException on SqlCommand.ExecuteScalar()
我正在運行一個執行查詢的方法,然后在關閉連接之前嘗試執行另一個查詢。 第一個查詢執行正常,但是第二個查詢導致:
SqlCommand.ExecuteScalar()方法上的InvalidOperationException。
我之前運行得很完美,但是發生了一些變化,似乎無法追蹤。 我正在測試在執行查詢之前先查看連接是關閉還是為空,但它不是null還是關閉。 所以這個讓我感到困惑。 任何人都知道發生了什么事嗎?
正在執行的查詢非常簡單:
SELECT COUNT(*)
FROM browsers;
我已經在SQL Server Management Studio中針對數據庫對此進行了測試,並且效果很好。
internal static String[,] executeSelect(SqlConnection conn, Query query, Editor reference)
{
if (conn == null)
{
throw new System.ArgumentNullException("The SqlConnection parameter to method CSED.SQLServerdb.executeSelect(...) is null");
}
if (query == null)
{
throw new System.ArgumentNullException("The Query parameter to method CSED.SQLSererdb.executeSelect(...) is null");
}
String[,] data = null;
SqlCommand cmd = null;
SqlDataReader rdr = null;
SqlCommand cmd2 = null;
SqlCommand cmd3 = null;
try
{
Debug.WriteLine("SQLServerdb.executeSelect - query: " + query.ToString());
cmd = new SqlCommand(query.ToString(), conn);
rdr = cmd.ExecuteReader();
Field[] flds = query.Fields;
int columns = flds.Length;
//Debug.WriteLine("SQLServerdb.executeSelect -columns: " + columns);
int recordCount = 0;
List<TableRow> rows = new List<TableRow>();
TableRow tr = null;
while (rdr.Read())
{
tr = new TableRow();
recordCount++;
for (int i = 0; i < columns; i++)
{
tr.Add(DRExtension.GetStringOrNull(rdr, i));
}
rows.Add(tr);
}
data = convert2DArray(rows, columns);
//If reference to the class Editor is null then this Database class isn't being used
//in conjunction with the Editor class. Therefore, we don't need to calculate the number
//of records returned from the query.
if (reference != null && reference.IsUsingSSP)
{
bool flag = false;
int foundrows = 0;
//GET THE NUMBER OF RECORDS RETURNED BASED ON THE ORIGINAL QUERY.
String queryStr = "";
if (query.HaveWhereConditions)
{
queryStr = "SELECT COUNT(*) FROM " + query.GetParentTable() + query.prepareWhere(query.WhereConditions);
}
else
{
queryStr = "SELECT COUNT(*) FROM " + query.GetParentTable();
flag = true;
}
Debug.WriteLine("queryStr: " + queryStr);
if(conn.State == ConnectionState.Closed)
Debug.WriteLine("conn is closed");
if(conn == null)
Debug.WriteLine("conn is NULL");
cmd2 = new SqlCommand(queryStr, conn);
object result = cmd2.ExecuteScalar(); //This is where I get the error
if (result != null)
{
foundrows = Convert.ToInt32(result);
query.IFilteredTotal = foundrows;
}
//Debug.WriteLine("SQLServerdb.executeSelect - foundrows: " + foundrows);
//GET THE TOTAL NUMBER OF RECORDS IN THE TABLE.
if (flag == false)
{
queryStr = "SELECT COUNT(*) FROM " + query.GetParentTable();
//Debug.WriteLine("SQLServerdb.executeSelect - queryStr: " + queryStr);
cmd3 = new SqlCommand(queryStr, conn);
result = cmd3.ExecuteScalar();
if (result != null)
{
int r = Convert.ToInt32(result);
// Debug.WriteLine("SQLServerdb.executeSelect - Number of Records in the Table: " + r);
query.ITotal = r;
}
}
else
{
query.ITotal = foundrows;
}
}
}
catch (SqlException sqle)
{
String extra = "SQL Problem: " + sqle.Message + Constants.NEWLINE;
extra += "Vendor Error: " + sqle.ErrorCode + Constants.NEWLINE;
log.Error(extra + sqle.StackTrace);
Debug.WriteLine(extra + sqle.StackTrace);
}
catch (Exception e)
{
log.Error("SQLServerdb.executeSelect - query: " + query.ToString());
log.Error(e.StackTrace);
Debug.WriteLine(e.StackTrace);
}
finally
{
// Always make sure result sets and statements are closed,
// and the connection is returned to the pool
if(cmd != null)
{
cmd.Dispose();
cmd = null;
}
if (cmd2 != null)
{
cmd2.Dispose();
cmd2 = null;
}
if (cmd3 != null)
{
cmd3.Dispose();
cmd3 = null;
}
if (rdr != null)
{
rdr.Close();
rdr.Dispose();
rdr = null;
}
if (conn != null)
{
conn.Close();
conn.Dispose();
conn = null;
}
}
return data;
}//end executeSelect me
當您執行COUNT命令時,以前的SqlDataReader仍處於打開狀態。 這會導致錯誤,因為如MSDN中所述
在使用SqlDataReader時,關聯的SqlConnection忙於為SqlDataReader提供服務,除了關閉它之外,無法對SqlConnection執行其他任何操作。 在調用SqlDataReader的Close方法之前,情況就是這樣。 例如,只有在調用“關閉”之后才能檢索輸出參數。
因此,如果這是導致錯誤的原因,則應在同一連接上發出另一個命令之前添加rdr.Close
。 (或者只是將MultipleActiveResultSets = True添加到您的連接字符串中)
側面非常重要注意:您創建要執行的字符串的體系結構存在缺陷。 對於每個與數據庫相關的代碼, SQL注入都是一種危險的可能性。 您應該需要在交易工具中添加參數化查詢 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.