Возвращать идентификатор после вставки C # с помощью SQL Server
Я знаю, что этот вопрос был на этом сайте много раз, но я не могу заставить мой код работать.
У меня есть оператор Insert
, и мне нужен идентификатор из этой инструкции на моей странице asp.net.
Я получаю return value 0
.
- Получить значение SCOPE_IDENTITY при вставке массивных записей для SQL TableType
- Получение SCOPE_IDENTITY из SQL Server на вставке
- Как разрешить нулевое значение Scope_Indentity в каскадной вставке?
- nextval и curval confusion в PostgreSQL
- IDENT_CURRENT возвращает последнее значение идентификатора, но SCOPE_IDENTITY не
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); }
- Какой тип данных возвращает метод SQLCommand ExecuteScalar ()?
- Предложение SQL Server OUTPUT
- Будет ли SCOPE_IDENTITY работать в этом случае?
- Профилировщик SQL Server, показывающий SCOPE_IDENTITY (), в то время как код ColdFusion не использует его ни в одном запросе
- Попытка передать недавний идентификатор с областью видимости scope_identity и его ошибку me: Указанный приказ недействителен
- Как включить Scope_Identity () в Int?
- SQL Server 2012 scope_identity советует
- Извлечь значение scope_identity в коде C # из хранимой процедуры в трехуровневой архитектуре
Попробуй это:
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);
EDIT: Я предполагаю, что метод ModifyData устанавливает свойство соединения и вызывает ExecuteNonQuery, поэтому ваш код будет выглядеть следующим образом:
objData.ModifyData(objCMD); int newId = Convert.ToInt32(newIdParam.Value);
Для этого вам не нужна переменная вывода. Вы можете просто использовать 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
делает, но посмотрите, как вы выполняете свою команду.
Это может быть так, поскольку это работает для SQL SERVER 2000
-
для использования в 2005 году +
OUTPUT INSERTED.ID
подобно
INSERT INTO Roles(UserId) OUTPUT INSERTED.ID VALUES(@UserId)
Предпочтительным решением (и AFAIK также является действительно действительно безопасным) является использование предложения OUTPUT
, как в этом примере:
DECLARE @newIdTable(newid INT); INSERT INTO table(...) OUTPUT INSERTED.ID INTO @newIdTable VALUES (...); SELECT TOP 1 newid FROM @newIdTable;
Я предлагаю вам поместить это в хранимую процедуру и вызвать ее с помощью ExecuteScalar
, которая вернет значение последнего выбора.
проверьте с помощью SCOPE_IDENTITY () ..