PostgreSQL触发器和传递参数

PostgreSQL触发器和传递参数,postgresql,stored-procedures,triggers,Postgresql,Stored Procedures,Triggers,这是一个多部分的问题 我有一张类似于: 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() RETURN

这是一个多部分的问题

我有一张类似于:

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() ;
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;
基本上,每次我在sales\u数据中插入新行时,我都希望生成一个新表,其中表名将定义为类似“salesdata\u Company\u Contract”的内容

因此,我的第一个问题是如何将公司和合同数据传递给触发器,以便将其传递给add_Contract()存储过程

从我的存储过程中,您将看到,每当将新数据插入salesdata\u Company\u合同表时,我还希望更新原始sales\u数据表。此触发器将执行以下操作:

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() ;
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_合同表,其中表名作为参数传递给存储过程,然后再次让该存储过程执行插入,然后更新主sales_数据表


您将采取什么方法?

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

来自我的第二种方法:1。忘记触发器2。编写一个名为“store_new_contract”的存储过程,并将公司名称和合同名称作为参数传递,这将(a)插入sales_数据表,(b)使用传递的参数创建补充表以生成字符串3。编写一个名为“alter_CONTACT_data”的存储过程,其中包含几个参数,如操作字符串(“insert”或“delete”),它将(a)从补充表中插入/删除,(b)更新销售数据表,并增加/减少顶部销售数字。然后从SQL查询中调用存储过程?