[英]SCOPE_IDENTITY is not working in asp.net?
我試圖通過逐個執行兩個查詢來插入記錄並獲取其新生成的id,但不知道為什么它給我以下錯誤。
Object cannot be cast from DBNull to other types
我的代碼如下:(我不想使用sql存儲過程)
SqlParameter sqlParam;
int lastInsertedVideoId = 0;
using (SqlConnection Conn = new SqlConnection(ObjUtils._ConnString))
{
Conn.Open();
using (SqlCommand sqlCmd = Conn.CreateCommand())
{
string sqlInsertValues = "@Name,@Slug";
string sqlColumnNames = "[Name],[Slug]";
string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + ");";
sqlCmd.CommandText = sqlQuery;
sqlCmd.CommandType = CommandType.Text;
sqlParam = sqlCmd.Parameters.Add("@Name", SqlDbType.VarChar);
sqlParam.Value = txtName.Text.Trim();
sqlParam = sqlCmd.Parameters.Add("@Slug", SqlDbType.VarChar);
sqlParam.Value = txtSlug.Text.Trim();
sqlCmd.ExecuteNonQuery();
//getting last inserted video id
sqlCmd.CommandText = "SELECT SCOPE_IDENTITY() AS [lastInsertedVideoId]";
using (SqlDataReader sqlDr = sqlCmd.ExecuteReader())
{
sqlDr.Read();
lastInsertedVideoId = Convert.ToInt32(sqlDr["lastInsertedVideoId"]);
}
}
}
//tags insertion into tag table
if (txtTags.Text.Trim().Length > 0 && lastInsertedVideoId > 0)
{
string sqlBulkTagInsert = "";
string[] tags = txtTags.Text.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tag in tags)
{
sqlBulkTagInsert += "INSERT INTO tags(VideoId, Tag) VALUES(" + lastInsertedVideoId + ", " + tag.Trim().ToLowerInvariant()+ "); ";
}
using (SqlConnection Conn = new SqlConnection(ObjUtils._ConnString))
{
Conn.Open();
using (SqlCommand sqlCmd = Conn.CreateCommand())
{
string sqlQuery = sqlBulkTagInsert;
sqlCmd.CommandText = sqlQuery;
sqlCmd.CommandType = CommandType.Text;
sqlCmd.ExecuteNonQuery();
}
}
}
如果可能的話,請檢查以上代碼編碼是否正確,或者我們可以進一步優化它以提高性能?
謝謝
對SCOPE_IDENTITY()的調用不會被視為與您正在執行的INSERT命令位於相同的“范圍”中。
基本上,您需要做的是更改線路:
string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + ");";
至:
string sqlQuery = "INSERT INTO videos(" + sqlColumnNames + ") VALUES(" + sqlInsertValues + "); SELECT SCOPE_IDENTITY() AS [lastInsertedVideoId]";
然后打電話
int lastVideoInsertedId = Convert.ToInt32(sqlCmd.ExecuteScalar());
而不是.ExecuteNonQuery和“//獲取最后插入的視頻ID”注釋后面的代碼塊。
應從第一個命令( SELECT
, RETURN
或OUT
)中提取SCOPE_IDENTITY()
並將其傳遞給下一個命令。 這樣,我的意思是SELECT_IDENTITY()
應該在第一個命令的末尾。 在SQL 2008中,還有一些額外的語法可以將值作為INSERT
一部分返回,這使得這更簡單。
或者更有效:將命令合並為一個以避免往返。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.