SCOPE_IDENTITY не работает в asp.net?

Я пытаюсь вставить запись и получить ее недавно сгенерированный идентификатор путем выполнения двух запросов один за другим, но не знаю почему ее предоставление мне следующая ошибка.

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();
            }
        }
    }

И также, если это возможно, проверьте, вышеупомянутый код, кодированный хорошо, или мы можем оптимизировать его больше для, улучшают производительность?

Спасибо

5
задан Prashant 28 January 2010 в 16:45
поделиться

2 ответа

Вызов 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 и блока кода, следующего за комментарием «// получение последнего вставленного идентификатора видео».

10
ответ дан 13 December 2019 в 22:07
поделиться

SCOPE_IDENTITY () следует извлечь из первой команды ( SELECT , RETURN или OUT ) и перешли в следующую команду. Под этим я подразумеваю, что SELECT_IDENTITY () должен быть в конце первой команды. В SQL 2008 есть дополнительный синтаксис для возврата значений как часть INSERT , что упрощает эту задачу.

Или, что более эффективно: объедините команды в одну, чтобы избежать повторных обращений.

0
ответ дан 13 December 2019 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: