2010-06-10 2 views
1

Это вопрос с несколькими частями.Триггеры и параметры передачи PostgreSQL

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

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»

Итак, мой первый вопрос: как я могу p p поместить данные Компании и Контракта в триггер, чтобы он мог быть передан в хранимую процедуру 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, где имя таблицы передается в хранимый proc как параметр, и снова запомните, что сохраненный proc выполняет вставку, а затем обновляет основную таблицу sales_data.

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

+0

из моего второго подхода: 1. забыть триггера 2. написать хранимую процедуру под названием «store_new_contract», и передать название компании и имя контракта в качестве параметров, которые будут (а) вставить в таблицу sales_data, (б) создайте дополнительную таблицу с использованием переданных параметров для генерации строки 3. напишите хранимую процедуру под названием «alter_contract_data» с несколькими параметрами, такими как строка действия («вставить» или «удалить»), которая будет (a) вставить/удалить из дополнительной таблицы, (b) обновите таблицу sales_data и увеличьте/уменьшите верхние показатели продаж. затем просто вызовите хранимую процедуру из SQL-запроса? – iandouglas

ответ

3

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

Смежные вопросы