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

如何使用C#ADO.Net从包含多行的SQL Server Insert命令中获取输出?,c#,sql-server,ado.net,C#,Sql Server,Ado.net,我想使用C#ADO.Net从这个insert命令接收所有输出主键 我在SQLServer2012 Studio中运行了这个程序,看到了包含所有值的结果表,那么是否可以从C#获取该表 我在C#ADO.NET中尝试的内容。但是DataTable没有从insertedOutput中获取任何值 SqlCommand cmd = new SqlCommand(insertQuery, this.conn); var insertedOutput = cmd.ExecuteReader(); DataT

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

我在SQLServer2012 Studio中运行了这个程序,看到了包含所有值的结果表,那么是否可以从C#获取该表

我在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代码。它很好用。(不确定“这个”是从哪里来的,但没有引起任何问题)

在调试器中,insertedOutput中有cmd.ExecuteReader()的结果,但我无法从dt(一个数据表变量)复制这些结果。

您的查询看起来很好(除了
this.created\u by
/
this.updated\u by
,这让我很困惑,但是…如果您说它有效的话…)

因此,我最初的想法是:是否有一个INSTEADOF触发器只错误地处理一行?尽管我希望报告:

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

以下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
}
使用(var conn=new SqlConnection(connectionString))
{
conn.Open();
常量字符串insertQuery=@”
插入dbo.Suspension
(托盘位置、处理托盘、创建日期时间、更新日期时间、,
[此.创建人],[此.更新人])
输出INSERTED.pkey值
(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);";
//通过数据表
DataTable dt=新的DataTable();
使用(SqlCommand cmd=newsqlcommand(插入查询,conn))
使用(var insertedOutput=cmd.ExecuteReader())
{
dt.负载(插入输出);
}
Console.WriteLine(dt.Rows.Count);//4
//通过手动阅读
var list=新列表();
使用(SqlCommand cmd=newsqlcommand(插入查询,conn))
使用(var insertedOutput=cmd.ExecuteReader())
{
while(insertedOutput.Read())
{
添加(insertedOutput.GetInt32(0));
}
}
Console.WriteLine(list.Count);//4
//衣冠楚楚
var id=conn.Query(insertQuery.ToList();
Console.WriteLine(id.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是您的标识列:)

//这会导致错误。
很抱歉,我将错误注释放错了位置。似乎dt.Load没有从insertedOutput获取值。(但没有编译错误)sql语句看起来甚至不合法(由等创建的
this.created_)-您能确认那里发生了什么吗?是的,我在sql Server Management Studio中尝试过。现在的主要问题是,我无法从dt.Load(insertedOutput)中获取值。为了完整性,我的创建脚本:
创建表暂停(pkey int not null identity(1,1),plallet\u position int,processing\u plallet\u pkey int,datetime\u created datetime,datetime\u updated datetime,[this.created\u by]int,[this.updated\u by]int)感谢您的支持,它现在可以与DataTable一起工作,我真的不明白为什么它昨天不工作。在这三种方式中,你能告诉我推荐哪一种吗。作为这篇文章中被删除的答案之一,我不知道是谁发布的,我说这(数据表)不是最好的方式。@gentlerainsky被删除的答案实际上是我写的,但它是基于对问题的错误理解。因此,我将重复我先前的观点,即
DataTable
不是读取几个整数的好方法(实际上,我很少使用
DataTable
)。“手动读取”代码很简单,但你最终写了很多东西——这就是为什么我写了“dapper”——一个免费提供的高性能数据访问工具;从上一个例子来看,这整件事变成了一行。所以是的,我会用它;P
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