2010-06-10 279 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”

所以我的第一个问题是我怎么能将公司和合同数据分配给触发器,以便将其传递给add_contract()存储过程?

从我的存储过程,你会看到,我也想更新每当新的数据插入到表salesdata_Company_Contract原SALES_DATA表。此触发会做这样的事情:

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; 

这当然会,要求我通过在这些存储过程和触发器各地的一些参数,我不知道(一)如果这甚至有可能,或者(b)实用,或者(c)最佳实践,我们应该把这个逻辑放到我们的其他软件中,而不是要求数据库为我们完成这项工作。

为了让我们的餐桌尺寸下降,因为我们将有几十万,每天的交易,我们已经决定使他们都对自己使用分区的公司和我们的数据合同字符串作为表名的一部分非常小;文件IO对我们来说更快,我们感觉我们会获得更好的性能。

感谢您的任何想法或方向。

我的想法现在已经写完了,可能我们需要编写存储过程,在这里我们将插入数据作为参数传递,并从其他软件中调用该过程,并使存储过程执行插入到“sales_data”然后创建另一个表。然后,有第二个存储过程将新数据插入到salesdata_Company_Contract表中,其中表名作为参数传递给存储过程,并再次使存储过程执行插入操作,然后更新主要sales_data表。

你会采取什么方法?

+0

从我的第二种方法: 1.忘记触发 2.写称为“store_new_contract”存储的过程,和通过公司名称和合同名作为参数,这将(a)中插入SALES_DATA表,(二)使用传递的参数创建补充表以生成字符串 3.编写一个名为'alter_contract_data'的存储过程,其中包含多个参数,如动作字符串('insert'或'delete'),它将(a)插入/删除从补充表中,(b)更新sales_data表并增加/减少最高销售数字。 然后只需从SQL查询调用存储过程? – iandouglas 2010-06-10 23:02:38

回答

3

它看起来像你只需要引用新的或旧的参数输入你的表。示例可以在优秀的Postgresql文档here中找到。将您的价值引用为NEW.Company和NEW.Contract。