PostgreSQL триггеры и параметры передачи - PullRequest
1 голос
/ 11 июня 2010

Это вопрос из нескольких частей.

У меня есть таблица, похожая на:

CREATE TABLE sales_data (
  Company character(50),
  Contract character(50),
  top_revenue_sum integer,
  top_revenue_sales integer,
  last_sale timestamp) ;

Я хотел бы создать триггер для новых вставок в эту таблицу, что-то вроде этого:

CREATE OR REPLACE FUNCTION add_contract()
RETURNS VOID
DECLARE
    myCompany   character(50),
    myContract  character(50),

BEGIN
    myCompany   = TG_ARGV[0];
    myContract  = TG_ARGV[1];

    IF (TG_OP = 'INSERT') THEN
        EXECUTE 'CREATE TABLE salesdata_' || $myCompany || '_' || $myContract || ' (
            sale_amount integer,
            updated TIMESTAMP not null,
            some_data varchar(32),
            country varchar(2)
        ) ;'
        EXECUTE 'CREATE TRIGGER update_sales_data BEFORE INSERT OR DELETE ON salesdata_'
            || $myCompany || '_' || $myContract || ' FOR EACH ROW EXECUTE update_sales_data( '
            || $myCompany || ',' || $myContract || ', revenue);' ;
    END IF;
END;
$add_contract$ LANGUAGE plpgsql;

CREATE TRIGGER add_contract AFTER INSERT ON sales_data FOR EACH ROW EXECUTE add_contract() ;

По сути, каждый раз, когда я вставляю новую строку в sales_data, я хочу создать новую таблицу, в которой имя таблицы будет определено как что-то вроде "salesdata_Company_Contract"

Итак, мой первый вопрос: как передать данные компании и контракта в триггер, чтобы их можно было передать хранимой процедуре add_contract ()?

Из моей хранимой процедуры вы увидите, что я также хочу обновлять исходную таблицу sales_data всякий раз, когда новые данные вставляются в таблицу salesdata_Company_Contract. Этот триггер будет делать что-то вроде этого:

CREATE OR REPLACE FUNCTION update_sales_data() RETURNS trigger as $update_sales_data$
DECLARE
    myCompany character(50) NOT NULL,
    myContract character(50) NOT NULL,
    myRevenue integer NOT NULL

BEGIN
    myCompany = TG_ARGV[0] ;
    myContract = TG_ARGV[1] ;
    myRevenue = TG_ARGV[2] ;

    IF (TG_OP = 'INSERT') THEN
        UPDATE sales_data SET
            top_revenue_sales = top_revenue_sales + 1,
            top_revenue_sum = top_revenue_sum + $myRevenue,
            updated = now()
        WHERE
            Company = $myCompany AND
            Contract = $myContract ;
    ELSIF (TG_OP = 'DELETE') THEN
        UPDATE sales_data SET
            top_revenue_sales = top_revenue_sales - 1,
            top_revenue_sum = top_revenue_sum - $myRevenue,
            updated = now()
        WHERE
            Company = $myCompany AND
            Contract = $myContract ;
    END IF;
END;
$update_sales_data$ LANGUAGE plpgsql;

Это, конечно, потребует, чтобы я передавал несколько параметров в рамках этих хранимых процедур и триггеров, и я не уверен (а), если это вообще возможно, (б) практическая или (в) лучшая практика и мы должны просто применить эту логику в нашем другом программном обеспечении вместо того, чтобы просить базу данных сделать эту работу за нас.

Чтобы уменьшить размеры наших таблиц, поскольку у нас будет сотни тысяч транзакций в день, мы решили разделить наши данные, используя строки Company и Contract, как часть самих имен таблиц, поэтому они все очень маленький по размеру; IO для нас быстрее, и мы почувствовали, что получим лучшую производительность.

Спасибо за любые мысли или указания.

Теперь, когда я написал все это, я подумал о том, что, возможно, нам нужно написать хранимые процедуры, в которых мы передаем данные вставки в качестве параметров, и вызываем их из нашего другого программного обеспечения, и хранимая процедура выполняет вставьте в «sales_data» затем создайте другую таблицу. Затем создайте вторую хранимую процедуру для вставки новых данных в таблицы salesdata_Company_Contract, где имя таблицы передается в хранимый процесс в качестве параметра, и снова этот сохраненный процесс выполняет вставку, а затем обновляет основную таблицу sales_data.

Какой подход вы бы выбрали?

1 Ответ

3 голосов
/ 11 июня 2010

Похоже, вам просто нужно сослаться на новые или старые параметры, входящие в вашу таблицу.Примеры можно легко найти в превосходной документации Postgresql здесь .Укажите ваши значения как NEW.Company и NEW.Contract.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...