Возврат идентификатора после вставки C# с использованием SQL Server

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

у меня есть Insert заявление, и мне нужен идентификатор из этого заявления на моей странице asp.net.

Я получаю return value 0,

public int newid { get; set; }

public void CreateAlbum(string _titel, string _name, string _thumb, int _userid)
{
    objCMD = new SqlCommand(@"INSERT INTO tblFotoalbum 
                                  (fldAlbumHead, fldAlbumName, fldAlbumThumb, fldUserID_FK)
                              VALUES 
                                  (@titel, @name, @thumb, @userid);

                              SET @newid = SCOPE_IDENTITY()");

    objCMD.Parameters.AddWithValue("@titel", _titel);
    objCMD.Parameters.AddWithValue("@name", _name);
    objCMD.Parameters.AddWithValue("@thumb", _thumb);
    objCMD.Parameters.AddWithValue("@userid", _userid);
    objCMD.Parameters.AddWithValue("@newid", newid);

    objData.ModifyData(objCMD);       
}

6 ответов

Решение

Попробуй это:

public int CreateAlbum(string _titel, string _name, string _thumb, int _userid)
{
    // define return value - newly inserted ID
    int returnValue = -1;

    // define query to be executed
    string query = @"INSERT INTO tblFotoalbum (fldAlbumHead, fldAlbumName, fldAlbumThumb, fldUserID_FK)
                              VALUES (@titel, @name, @thumb, @userid);
                     SELECT SCOPE_IDENTITY();"

    // set up SqlCommand in a using block   
    using (objCMD = new SqlCommand(query, connection)) 
    {
        // add parameters using regular ".Add()" method 
        objCMD.Parameters.Add("@titel", SqlDbType.VarChar, 50).Value = _titel;
        objCMD.Parameters.Add("@name", SqlDbType.VarChar, 100).Value = _name;
        objCMD.Parameters.Add("@thumb", SqlDbType.VarChar, 100).Value = _thumb;
        objCMD.Parameters.Add("@userid", SqlDbType.VarChar, 25).Value = _userid;

        // open connection, execute query, close connection
        connection.Open();
        object returnObj = objCMD.ExecuteScalar();

        if(returnObj != null)
        {
           int.TryParse(returnObj.ToString(), out returnValue);
        }

        connection.Close();
    }

    // return newly inserted ID
    return returnValue;
}

Не уверен, как вы можете интегрировать это с вашим objData класс - может быть, вам нужно добавить новый метод в этот класс DAL для этого.

Проверьте Можем ли мы прекратить использовать AddWithValue() уже? и прекратить использование .AddWithValue() - это может привести к неожиданным и неожиданным результатам...

Учитывая оператор SQL, который вы используете, вам нужно настроить @newid в качестве выходного параметра:

var newIdParam = objCMD.Parameters.Add("@newid", SqlDbType.Int32)
newIdParam.Direction = ParameterDirection.OutPut;

затем вы выполняете команду с помощью ExecuteNonQuery, и после этого вы можете прочитать параметр ouptut:

objCmd.ExecuteNonQuery();
int newId = Convert.ToInt32(newIdParam.Value);

РЕДАКТИРОВАТЬ: я предполагаю, что метод ModifyData устанавливает свойство подключения и вызывает ExecuteNonQuery, поэтому ваш код будет:

objData.ModifyData(objCMD);      
int newId = Convert.ToInt32(newIdParam.Value);

Если вы используете CommandText, не забудьте добавить "SELECT SCOPE_IDENTITY()" в конце строки CommandText.

Это может быть так, как это работает для SQL SERVER 2000

  • для 2005+ использования

    OUTPUT INSERTED.ID

подобно

INSERT INTO Roles(UserId)
OUTPUT INSERTED.ID
VALUES(@UserId)

Проверить с помощью SCOPE_IDENTITY ()..

https://msdn.microsoft.com/en-IN/library/ms190315.asp

Предпочтительным решением (и AFAIK также единственным действительно безопасным) является использование OUTPUT предложение как в этом примере:

DECLARE @newIdTable(newid INT);
INSERT INTO table(...) OUTPUT INSERTED.ID INTO @newIdTable VALUES (...);
SELECT TOP 1 newid FROM @newIdTable;

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

Вам не нужна выходная переменная, чтобы сделать это. Вы могли бы просто использовать SELECT SCOPE_IDENTITY() чтобы вставить последний идентификатор в базу данных и использовать ExecuteScalar() метод из DbCommand,

public int newid { get; set; }

public void CreateAlbum(string _titel, string _name, string _thumb, int _userid)
{
    objCMD = new SqlCommand(@"INSERT INTO tblFotoalbum 
                           (fldAlbumHead, fldAlbumName, fldAlbumThumb, fldUserID_FK)
                           VALUES 
                           (@titel, @name, @thumb, @userid);

                           SELECT SCOPE_IDENTITY()");

    objCMD.Parameters.AddWithValue("@titel", _titel);
    objCMD.Parameters.AddWithValue("@name", _name);
    objCMD.Parameters.AddWithValue("@thumb", _thumb);
    objCMD.Parameters.AddWithValue("@userid", _userid);
    objCMD.Parameters.AddWithValue("@newid", newid);

    objData.ModifyData(objCMD);     


    newid = (int)objCMD.ExecuteScalar();
}

Я не знаю objData объект делает, но посмотрите, как вы выполняете свою команду.

Другие вопросы по тегам