如何使用C#ADO.Net从SQL Server Insert命令中获取多行的输出

本文关键字:获取 输出 命令 Insert C#ADO 何使用 Net Server SQL | 更新日期: 2023-09-27 18:26:17

我想使用C#ADO.Net.从这个插入命令接收所有输出主键

我在SQLServer2012Studio中运行了这个程序,我看到了包含所有值的结果表,所以有可能从C#中获取该表吗?

INSERT INTO dbo.Suspension 
(pallet_position, processing_pallet_pkey, datetime_created, datetime_updated,
created_by, updated_by) 
OUTPUT INSERTED.pkey VALUES
(1, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(2, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(3, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(4, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2);

我在C#ADO.NET中尝试过。但是DataTable没有从insertedOutput中获得任何值。

SqlCommand cmd = new SqlCommand(insertQuery, this.conn);
var insertedOutput = cmd.ExecuteReader(); 
DataTable dt = new DataTable();
dt.Load(insertedOutput); // something wrong here

注意到我从调试器中复制了SQL代码。它运行良好。(不确定"这个"是从哪里来的,但它没有引起任何问题)

在调试器中,有来自cmd的结果。insertedOutput中的ExecuteReader(),但我无法从dt(DataTable变量)复制这些结果。

如何使用C#ADO.Net从SQL Server Insert命令中获取多行的输出

您的查询看起来不错(除了this.created_by/this.updated_by,这让我很困惑,但…如果您说它有效…)

因此,我最初的想法是:你可能有一个只错误地处理一行的替代触发器吗?尽管我希望报告:

如果DML语句包含不带INTO子句的OUTPUT子句,则DML语句的目标表"dbo.Suspension"不能具有任何已启用的触发器。

以下3种读取sql(或与之非常相似的版本)的方法都很好:

using (var conn = new SqlConnection(connectionString))
{
    conn.Open();
    const string insertQuery = @"
INSERT INTO dbo.Suspension
(pallet_position, processing_pallet_pkey, datetime_created, datetime_updated,
[this.created_by], [this.updated_by]) 
OUTPUT INSERTED.pkey VALUES
(1, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(2, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(3, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(4, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2);";
    // via datatable
    DataTable dt = new DataTable();
    using (SqlCommand cmd = new SqlCommand(insertQuery, conn))
    using (var insertedOutput = cmd.ExecuteReader())
    {
        dt.Load(insertedOutput);
    }
    Console.WriteLine(dt.Rows.Count); // 4
    // via manual read
    var list = new List<int>();
    using (SqlCommand cmd = new SqlCommand(insertQuery, conn))
    using (var insertedOutput = cmd.ExecuteReader())
    {
        while(insertedOutput.Read())
        {
            list.Add(insertedOutput.GetInt32(0));
        }
    }
    Console.WriteLine(list.Count); // 4
    // via dapper
    var ids = conn.Query<int>(insertQuery).ToList();
    Console.WriteLine(ids.Count); // 4
}

您可以使用插入行中标识列的值并将其存储在表中,然后从中获取值。

DECLARE @tblIds TABLE (id int)
Insert into dbo.Suspension 
(pallet_position, processing_pallet_pkey, datetime_created, datetime_updated,
created_by, updated_by)
OUTPUT inserted.pkey INTO @tblIds
values
(1, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(2, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(3, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2), 
(4, 2, '20141013 16:27:25.000', '20141013 16:27:25.000', 2, 2)
select * from @tblIds

这里我假设pkey是您的身份列:)