我有以下问题。我有一个存储过程,用于更新或将数据插入到名为 UpdateData 的数据库中。它看起来大致是这样的(虽然简化了):
CREATE PROCEDURE [dbo].[UpdateData]
@dataId as int,
@data as int,
AS
BEGIN
SET NOCOUNT ON;
declare @count int
select @count = (select COUNT(*) from DataTable data where data.id = @dataId)
if @count = 1
begin
update DataTable set data = @data from DataTable where data.id = @dataId
select 'Updated' [operation] , @@ROWCOUNT [count]
end
else
begin
insert into DataTable (id, data) values(@dataId, @data)
select 'Inserted' [operation] , @@ROWCOUNT [count]
end
END
我使用 DBI 通过准备好的语句迭代我的数据从 perl 调用这个存储过程。然后我使用对 fetchrow_array 的调用来获取有关执行了哪个操作的信息:
my $dbh = getDBHandle($debug);
foreach (@Data) {
$updateData->execute($->[0], $_->[1]);
my @row = $updateData->fetchrow_array;
my ($action, $count) = ($row[0], $row[1]);
print $row[0] .",$action, $count\n";
}
发生的情况是,一旦运行任何更新语句,随后所有插入的操作描述都会从“插入”截断为“插入”。我认为这是因为字符串 'updated' 比 'inserted' 少了一个字符,一旦 fetchrow_array 在列中使用该字符串调用,它就会重置某种限制。如果我使两个描述字符串之间的区别不止一个,比如修改存储过程以使用“更新”而不是“更新”(两个字符与“插入”的差异)
select 'Update' [operation] , @@ROWCOUNT [count]
我得到错误:
DBD::ODBC::st fetchrow_array failed: [Microsoft][ODBC SQL Server Driver]String data, right truncation (SQL-01004)
总而言之,输出看起来像
1,插入,10
2,更新,15
3,插入,20
4,更新,5
关于为什么执行不独立以及解决此问题的最佳方法是什么的任何想法。我知道我可以使动作相同,但我想要一个更好的解决方案。
编辑:一个后续问题。如果 UpdateData 过程需要调用另一个也返回数据的过程。是否有可能在 Perl 中获得两个结果集。一个来自内部程序,一个来自外部程序。现在, >fetchrow_array 只获取内部结果集。
编辑 2:关于数据截断的原始问题,我想知道为什么在每次执行后调用 $updateData->finish 不会导致每次执行时都重置宽度。IE
foreach (@Data) {
$updateData->execute($->[0], $_->[1]);
my @row = $updateData->fetchrow_array;
my ($action, $count) = ($row[0], $row[1]);
print $row[0] .",$action, $count\n";
$updateData->finish;
}