Идентификатор возврата на INSERT?
У меня есть запрос INSERT, и я хочу, чтобы DB возвращал идентификатор только что вставленной строки.
sqlString = "INSERT INTO MagicBoxes (OwnerID, Key, Name, Permissions, Active, LastUpdated) VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) SET @ID = SCOPE_IDENTITY();";
cmd = new SqlCommand(sqlString, con);
cmd.Parameters.AddWithValue("@OwnerID", OwnerID);
cmd.Parameters.AddWithValue("@BoxKey", BoxKey);
cmd.Parameters.AddWithValue("@BoxName", BoxName);
cmd.Parameters.AddWithValue("@Username", Username);
cmd.Parameters.AddWithValue("@Date", DateTime.Now);
cmd.ExecuteNonQuery();
У меня в настоящее время это, я не уверен, что мне нужно сделать дальше...
Ответы
Ответ 1
Вам просто нужно добавить @ID в коллекцию params, а затем восстановить его, как это,
cmd.Parameters.Add("@ID", SqlDbType.Int, 4).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
//Now just read the value of: cmd.Parameters["@ID"].value
Или, если вы предпочитаете этот синтаксис:
SqlParameter param = new SqlParameter("@ID", SqlDbType.Int, 4);
param.Direction = ParameterDirection.Output;
cmd.Parameters.Add(param);
Ответ 2
У вас есть два варианта; вы можете объявить параметр Output
под названием @ID
; или - вы можете изменить конец на SELECT SCOPE_IDENTITY()
и просто использовать:
int id = (int)cmd.ExecuteScalar();
Я предпочитаю подход с формальным параметром, но ExecuteScalar
работает хорошо.
Ответ 3
Так как SQL Server 2008 было предложение OUTPUT, добавленное к синтаксису TSQL. Это позволяет вам иметь данные, на которые влияет запрос DML, добавленный в табличный поток данных.
Хотя запрос SCOPE_IDENTITY() после запроса возвращает правильную информацию, он заставляет SQL Server выполнять 2 запроса, в которых предложение вывода ограничивает это одним запросом.
Зная это, выполняемый запрос может быть изменен следующим образом (Предполагая, что [Id]
- это имя идентификатора):
INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated)
OUTPUT INSERTED.Id
VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date)
Другая проблема заключается не в использовании SqlCommand
. Большинство объектов Sql...
в ADO.net реализуют IDisposable
и должны быть утилизированы должным образом.
Объединяя все вместе, я бы выполнил эту часть кода следующим образом:
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["db"].ConnectionString))
using (var cmd = new SqlCommand(@"
INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated)
OUTPUT INSERTED.Id
VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) ", conn))
{
cmd.Parameters.AddRange(new[]
{
new SqlParameter("@OwnerID", SqlDbType.Int).Value = OwnerID,
new SqlParameter("BoxKey", SqlDbType.VarChar).Value = BoxKey,
new SqlParameter("@BoxName", SqlDbType.VarChar).Value = BoxName,
new SqlParameter("@Date", SqlDbType.DateTime).Value = DateTime.Now
});
conn.Open();
var id = (int)cmd.ExecuteScalar();
}
Ответ 4
Добавьте это к вашим параметрам
SqlParameter IDParameter = new SqlParameter("@ID",SqlDbType.Int);
IDParameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add(IDParameter);
После выполнения вы можете получить идентификатор
int id = (int)IDParameter.Value;
Ответ 5
Почему бы вам не вызвать процедуру хранилища. Передайте значения в процедуру хранилища, чтобы получить введенные значения, и из SP верните последнее начальное значение, вставленное с помощью SCOPE_IDENTITY().
Надейтесь на эту помощь.