Reputation: 959
HI,
I use perl DBI do() which will execute the below SQL block like below which executes in 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); };
Now i can see that the return value $result only contains the rows affected by the first update statement.So i dont have any information about the deleted rows , But i can see that the rows are indeed deleted in the Database.
In general if i have a INSERT , DELETE , UPDATE statement inside a BEGIN TRAN , COMMIT TRAN block and if the entire block will be submitted by DBI do() method , I would need to know the exact number of statements inserted , number of statements updated and number of statements deleted.
I know that SQL SERVER's @@ROWCOUNT will give me the rows affected after each statement , but that is a SQL server variable which will be visible only inside the block. Is it possible to get the data into perl ?
Any help ?
Upvotes: 0
Views: 3066
Reputation: 17703
What database access method is in use? Is there any reason for not moving the transaction logic outside of the T-SQL?
If you're using DBI something along these lines should satisfy your requirements:
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"; }
This snippet doesn't take into account making the database connection, error handling, or closing the connection, but DBI documentation should help there. http://metacpan.org/pod/DBI
You probably also want to look into the prepare and bind_param DBI methods if you're planning on executing multiple non-select statements.
Upvotes: 1
Reputation: 129559
To get the value of @@ROWCOUNT
, you need to add SELECT @@ROWCOUNT 'rowcount'
as the last command before "COMMIT TRAN", then the whole SQL will return the result set consising of 1 row with 1 'rowcount' column.
The only caveat is that since do()
method doesn't provide you with results sets, you need to switch to prepare()/fetchrow_array()/fetchrow_array()
instead, or use one of the wrapper methods like nsql()
from your DB library if those are available.
For a detailed inserted/updated/deleted breakdown, simply save those @@ROWCOUNTs into variables after the insert/update/delete, and select the counts afterwards:
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'
Upvotes: 2