Вычисление количества строк, на которые влияет пакетный запрос в PostgreSQL


Во-первых, да, я прочитал документацию для заявления DO :) http://www.postgresql.org/docs/9.1/static/sql-do.html

Итак, мой вопрос:

Мне нужно выполнить некоторый динамический блок кода, содержащий инструкции UPDATE, и вычислить количество всех затронутых строк. Я использую Ado.Net провайдера.

В Oracle решение будет иметь 4 шага:

  1. добавьте параметр InputOutput "N" в команду
  2. добавить начать ... Конец; к команда
  3. добавьте : N := :N + sql%rowcount после каждого оператора.
  4. дело сделано! Мы можем прочитать N параметров из команды, после того, как выполним ее.

Как это сделать с PostgreSQL? Я использую npgsql provider, но могу мигрировать в devard, если это поможет.

2 4

2 ответа:

DO блоки операторов хороши для выполнения динамического SQL. Они не годятся для возврата ценностей. Используйте plpgsql функция для этого.

Ключевое утверждение, которое вам нужно:

GET DIAGNOSTICS integer_var = ROW_COUNT;

Подробности в руководстве.

Пример кода:

CREATE OR REPLACE FUNCTION f_upd_some()
  RETURNS integer AS
$func$
DECLARE
   ct int;
   i  int;
BEGIN
   EXECUTE 'UPDATE tbl1 ...';       -- something dynamic here
   GET DIAGNOSTICS ct = ROW_COUNT;  -- initialize with 1st count

   UPDATE tbl2 ...;                 -- nothing dynamic here 
   GET DIAGNOSTICS i = ROW_COUNT;
   ct := ct + i;                    -- add up

   RETURN ct;
END
$func$  LANGUAGE plpgsql;

Вызов:

SELECT * FROM f_upd_some();

Мое решение довольно простое. В Oracle мне нужно использовать переменные для вычисления суммы обновленных строк, потому что command.ExecuteNonQuery() возвращает только количество строк, затронутых последним обновлением в пакете.

Однако npgsql возвращает сумму всех строк, обновленных всеми запросами обновления. Поэтому мне нужно только вызвать command.ExecuteNonQuery() и получить результат без каких-либо переменных. Гораздо проще, чем с Оракулом.