我有一批需要在一个事务中插入的行,第一行是标题,所有后续行必须引用第一行。
这就是我试图插入第一行的方式:
using ( var connection = new SqlConnection( _connectionString ) )
{
connection.Open();
var transaction = connection.BeginTransaction();
try
{
// create the record header
using ( var createRecordCommand = connection.CreateCommand() )
{
createRecordCommand.CommandText =
"DECLARE @RecordId INT;" +
$"INSERT INTO ..." +
"SET @RecordId = scope_identity();";
createRecordCommand.Transaction = transaction;
createRecordCommand.ExecuteNonQuery();
我在后续语句中努力引用RecordId,似乎认为变量@RecordId未在下面的代码段中声明。 '必须声明标量变量“@RecordId”。'
using ( var createAttributeCommand = connection.CreateCommand() )
{
createAttributeCommand.Transaction = transaction;
createAttributeCommand.CommandText =
$"INSERT INTO ... (RecordId,...) VALUES (@RecordId,...)";
同时将@RecordId变量作为参数提取也很困难,当我将下面的行与DECLARE @RecordId INT;
createRecordCommand.Parameters.Add( new SqlParameter( "@RecordId", SqlDbType.Int ) { Direction = ParameterDirection.Output } );
答案 0 :(得分:0)
我没有意识到你可以在事务提交之前提取数据,假设因为ExecuteScalar()不起作用,我会遇到同样的问题。
正如评论中指出的那样,存储过程可能是最好的解决方案,SQL专家听起来像一段时间后破碎的记录; p。这将是短期过于复杂,因为存在变量参数,验证和值将根据业务逻辑进行变异。作为一个团队,我们在C#中更加自如,因此逻辑将保持不变,直到完全被确定为止。
结果代码如下, N.B。在实际代码中,将所有变量作为参数传递以避免SQL注入,我们是,这只是演示:
using ( var connection = new SqlConnection( _connectionString ) )
{
connection.Open();
var transaction = connection.BeginTransaction();
try
{
// create the record header
using ( var createRecordCommand = connection.CreateCommand() )
{
createRecordCommand.CommandText =
//"DECLARE @RecordId INT;" +
$"INSERT INTO ..." +
"SET @RecordId = scope_identity();";
createRecordCommand.Transaction = transaction;
createRecordCommand.Parameters.Add( new SqlParameter( "@RecordId", SqlDbType.Int ) { Direction = ParameterDirection.Output } );
createRecordCommand.ExecuteNonQuery();
recordId = (int) createRecordCommand.Parameters["@RecordId"].Value;
// ...
using ( var createAttributeCommand = connection.CreateCommand() )
{
createAttributeCommand.Transaction = transaction;
createAttributeCommand.CommandText =
$"INSERT INTO ... (RecordId,...) VALUES ({recordId},...)";
// ...
transaction.Commit();