Perl DBI - 获取事务中每个语句影响的记录
Posted
技术标签:
【中文标题】Perl DBI - 获取事务中每个语句影响的记录【英文标题】:Perl DBI - Getting records affected of each statement in a transaction 【发布时间】:2011-05-11 06:31:56 【问题描述】:嗨,
我使用 perl DBI do(),它将执行下面的 SQL 块,如下所示,在 SQL SERVER 2005 中执行
eval my $result = do(<<SQL); BEGIN TRAN UPDATE table1 SET col1 = 999 where date = '2010-08-27' DELETE FROM table1 where date = '2010-08-30' COMMIT TRAN SQL $logger->info($result); ;
现在我可以看到返回值 $result 只包含受第一个更新语句影响的行。所以我没有关于已删除行的任何信息,但我可以看到这些行确实在数据库中被删除了。
一般来说,如果我在 BEGIN TRAN、COMMIT TRAN 块中有一个 INSERT、DELETE、UPDATE 语句,并且如果整个块将由 DBI do() 方法提交,我需要知道插入语句的确切数量,更新的语句数和删除的语句数。
我知道 SQL SERVER 的 @@ROWCOUNT 会在每条语句之后给我受影响的行,但这是一个 SQL 服务器变量,仅在块内可见。是否可以将数据放入 perl 中?
有什么帮助吗?
【问题讨论】:
【参考方案1】:要获取@@ROWCOUNT
的值,您需要在“COMMIT TRAN”之前添加SELECT @@ROWCOUNT 'rowcount'
作为最后一个命令,然后整个SQL 将返回由1 行和1 'rowcount' 列组成的结果集。
唯一需要注意的是,由于do()
方法不为您提供结果集,因此您需要切换到prepare()/fetchrow_array()/fetchrow_array()
,或者使用数据库库中的nsql()
之类的包装方法之一(如果有)可用。
对于详细的插入/更新/删除细分,只需在插入/更新/删除后将这些 @@ROWCOUNT 保存到变量中,然后选择计数:
declare @update_count int
declare @delete_count int
UPDATE table1 SET
col1 = 999 where date = '2010-08-27'
SELECT @update_count = @@ROWCOUNT
DELETE FROM table1
where date = '2010-08-30'
SELECT @delete_count = @@ROWCOUNT
SELECT @update_count 'update_count', @delete_count '@delete_count'
【讨论】:
【参考方案2】:正在使用什么数据库访问方法?是否有任何理由不将事务逻辑移到 T-SQL 之外?
如果您正在使用 DBI,那么这些方面的内容应该可以满足您的要求:
eval
$dbh->begin_work;
$dbh->do("CREATE TABLE #temp (col1 INTEGER, date DATETIME);");
# Inserts
my $inserted = $dbh->do("INSERT INTO #temp VALUES (1,'2010-08-27');");
$inserted += $dbh->do("INSERT INTO #temp SELECT 999,'2010-08-27' UNION SELECT 5, '2010-08-30';");
# Updates
my $updated = $dbh->do("UPDATE #temp SET col1 = 999 WHERE date = '2010-08-27';");
# Deleted
my $deleted = $dbh->do("DELETE FROM #temp WHERE date = '2010-08-30';");
$dbh->commit;
print "Inserted $inserted rows.\n";
print "Updated $updated rows.\n";
print "Deleted $deleted rows.\n";
这个 sn-p 没有考虑建立数据库连接、错误处理或关闭连接,但 DBI 文档应该对此有所帮助。 http://metacpan.org/pod/DBI
如果您计划执行多个非选择语句,您可能还想研究 prepare 和 bind_param DBI 方法。
【讨论】:
我有很多 INSERT、DELETE、UPDATE 作为单个事务运行。即为什么我需要在 T-SQL BEGIN TRAN 和 COMMIT TRAN 块中包含所有语句。所以我能想到的唯一方法是将整个 SQL 作为一个字符串,prepare() 它,执行并获取将有计数的返回结果。将在 begin_work 中执行多个操作并按照您所写的方式提交会产生相同的效果。完全是酸吗? 是的,在 begin_work 和 rollback/commit 之间有多个 do 语句将与 T-SQL 中的 BEGIN TRANSACTION 和 ROLLBACK TRANSACTION/COMMIT TRANSACTION 块具有相同的效果。您可以通过将 $dbh->begin_work 替换为 $dbh->AutoCommit = 0; 来测试此行为,然后在不同的 DML 操作之后添加提交和回滚。无论事务是回滚还是提交,打印都会显示受影响的行数,但转储表结果应显示预期数据。以上是关于Perl DBI - 获取事务中每个语句影响的记录的主要内容,如果未能解决你的问题,请参考以下文章
Perl DBI:带有 OR 语句的奇数绑定变量(需要 y 时使用 x 绑定变量调用)