.Net SqlDataAdapter получить идентификатор после вставки со значением по умолчанию в столбце

Мне нужен способ получить значение идентичности после вставки с помощью SqlDataAdapter.

Я проверил следующие случаи:

  1. Если после вставки я запускаю select @@identity, возвращаемое значение будет неправильным, если есть другие триггеры, выполняющие вставки.

  2. Если я запускаю select scope_identity() ПОСЛЕ вставки, это не тот же пакет, поэтому идентификатор равен нулю

  3. Решением было запустить select scope_identity() в том же пакете, поэтому я изменил InsertCommand адаптера (см. Код ниже)

В этот момент я столкнулся с еще одной проблемой: adapter.Update сбрасывает команду вставки, поэтому он не запускает второй выбор (scope_identity()). Если строитель очищает команду с помощью builder.RefreshSchema(), эта проблема решается, поскольку команда вставки остается неизменной. С другой стороны, если вставка такова:

adapter.InsertCommand.CommandText = "INSERT INTO [clinics].[InstutionContracts] ( [DateStart], [DateEnd], [ContractType], [DataDeTest]) VALUES (@p1, @p2, @p3, @p4);SELECT SCOPE_IDENTITY() as SkunkIdReturn"

Столбец SQL Server DataDeTest не допускает нулевые значения, но имеет значение по умолчанию getdate(), поэтому он генерирует исключение вставленного значения NULL ( @p4 равно NULL). Помните, что в этом случае я запускаю перед builder.RefreshSchema(). Если бы я не запустил это, адаптер обновил бы только первые три столбца, строка была бы вставлена ​​корректно, но я не получил идентификатор в table.Rows[0]. Вот мой код:

DbCommand command = null;
DbDataAdapter adapter = null;

command = new SqlCommand();
adapter = new SqlDataAdapter();

var factory = bProviderFactories.GetFactory("system.data.sqlclient");

var builder = factory.CreateCommandBuilder();
builder.DataAdapter = adapter;

DbCommand command2 = null;
command2 = new SqlCommand();
command2 = builder.GetInsertCommand();
builder.RefreshSchema();  

command2.CommandText += ";SELECT SCOPE_IDENTITY() as SkunkIdReturn"; // get id
adapter.InsertCommand = command2;

var table = new DataTable(tableName);
retSupd.rows = new List<row>();
var lrv = new List<row>();

.... 

var identity = "";

if (isSqlServerConnection && curRow.status == Status.Nou)
{

    adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.Both;
    adapter.Update(table);
    identity = table.Rows[0][table.Rows[0].ItemArray.Length - 1].ToString(); // is retrieved only if there are not null values on default columns
    // otherwise, it returns "cannot insert NULL value in not NULL columns" because the insert command is not adapted

}
else
{
    adapter.Update(table); // it works (even on default value columns), but I don't get the identity
}

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

1 ответ

Вот фрагмент:

USE AdventureWorks2012;  
GO  
--Display the value of LocationID in the last row in the table.  
SELECT MAX(LocationID) FROM Production.Location;  
GO  
INSERT INTO Production.Location (Name, CostRate, Availability, ModifiedDate)  
VALUES ('Damaged Goods', 5, 2.5, GETDATE());  
GO  
SELECT @@IDENTITY AS 'Identity';  
GO  

из документов Microsoft.

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