Perl DBI - получение записей, затрагиваемых каждым оператором в транзакции - PullRequest
0 голосов
/ 17 ноября 2010

HI,

Я использую 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 содержит только те строки, на которые повлиял первый оператор обновления. Так что у меня нет никакой информации об удаленных строках, но я вижу, что строки действительно удалены в базе данных.

В общем, если у меня есть оператор INSERT, DELETE, UPDATE внутри блока BEGIN TRAN, COMMIT TRAN и если весь блок будет передан методом DBI do (), мне нужно знать точное количество вставленных операторов, количество операторовобновлено и количество заявлений удалено.

Я знаю, что @@ ROWCOUNT SQL SERVER даст мне строки, на которые влияют после каждого оператора, но это переменная сервера SQL, которая будет видна только внутри блока.Можно ли получить данные в Perl?

Любая помощь?

Ответы [ 2 ]

2 голосов
/ 17 ноября 2010

Чтобы получить значение @@ROWCOUNT, вам нужно добавить SELECT @@ROWCOUNT 'rowcount' в качестве последней команды перед «COMMIT TRAN», тогда весь 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'
1 голос
/ 17 ноября 2010

Какой метод доступа к базе данных используется?Есть ли какая-либо причина не перемещать логику транзакций за пределы 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"; }

Этот фрагмент не соответствуетНе принимайте во внимание соединение с базой данных, обработку ошибок или закрытие соединения, но документация DBI должна помочь в этом.http://metacpan.org/pod/DBI

Возможно, вы также захотите изучить методы DBI prepare и bind_param, если планируете выполнить несколько операторов без выбора.

...