【发布时间】:2010-06-10 22:25:04
【问题描述】:
这是一个多部分的问题。
我有一个类似的表:
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;
当然,这需要我在这些存储过程和触发器中传递几个参数,我不确定 (a) 这是否可能,或 (b) 实用,或 (c) 最佳实践我们应该把这个逻辑放到我们的其他软件中,而不是让数据库为我们做这项工作。
为了减小我们的表大小,因为我们每天将有数十万个事务,我们决定使用公司和合同字符串作为表名本身的一部分来对我们的数据进行分区,这样它们都非常体积小;文件 IO 对我们来说更快,我们觉得我们会获得更好的性能。
感谢您的任何想法或指导。
我的想法是,既然我已经写了所有这些,也许我们需要编写存储过程,我们将插入数据作为参数传递,并从我们的其他软件中调用它,并让存储过程执行插入“sales_data”,然后创建另一个表。然后,有第二个存储过程将新数据插入到 salesdata_Company_Contract 表中,其中表名作为参数传递给存储过程,再次让该存储过程执行插入,然后更新主 sales_data 表。
你会采取什么方法?
【问题讨论】:
-
我的第二种方法:1.忘记触发器2.编写一个名为'store_new_contract'的存储过程,并将公司名称和合同名称作为参数传递,它将(a)插入sales_data表, (b) 使用传递的参数创建补充表以生成字符串 3. 编写一个名为“alter_contract_data”的存储过程,其中包含多个参数,如操作字符串(“插入”或“删除”),它将 (a) 插入/删除从补充表中,(b) 更新 sales_data 表并增加/减少最高销售数据。那么只需从 SQL 查询中调用存储过程?
标签: postgresql stored-procedures triggers