【问题标题】:Auto Table Partitioning -PostgreSQL- ERROR: too few arguments for format()自动表分区 -PostgreSQL- 错误:format() 的参数太少
【发布时间】:2019-10-03 14:49:04
【问题描述】:

我正在尝试使用下面的函数和下面的触发器对我的 oltpsales 表进行自动分区,但随后我尝试在表上执行插入操作,但出现下面的错误代码。我在下面引用了一些主题,欢迎提出建议。

INSERT with dynamic table name in trigger function

Postgres format string using array

错误:format() 的参数太少 上下文:PL/pgSQL 函数 testoltpsales_insert_function() 第 17 行的 EXECUTE

 CREATE TRIGGER testoltpsales_insert_trg
    BEFORE INSERT ON myschema."testoltpsales"
    FOR EACH ROW EXECUTE PROCEDURE testoltpsales_insert_function();
CREATE OR REPLACE FUNCTION testoltpsales_insert_function()
RETURNS TRIGGER AS $$
DECLARE
    partition_date TEXT;
    partition_name TEXT;
    start_of_month TEXT;
    end_of_next_month TEXT;
BEGIN
    partition_date := to_char(NEW."CreateDateTime",'YYYY_MM');
    partition_name := 'testoltpsaless_' || partition_date;
    start_of_month := to_char((NEW."CreateDateTime"),'YYYY-MM') || '-01';
    end_of_next_month := to_char((NEW."CreateDateTime" + interval '1 month'),'YYYY-MM') || '-01';
IF NOT EXISTS
    (SELECT 1
     FROM   information_schema.tables 
     WHERE  table_name = partition_name) 
THEN
    EXECUTE format(E'CREATE TABLE %I (CHECK ( date_trunc(\'day\', %I.CreateDateTime) >= ''%s'' AND date_trunc(\'day\', %I.CreateDateTime) < ''%s'')) INHERITS (myschema."Testoltpsaless")', 
    VARIADIC ARRAY [partition_name, start_of_month,end_of_next_month]);

    RAISE NOTICE 'A partition has been created %', partition_name;

    -- EXECUTE format('GRANT SELECT ON TABLE %I TO readonly', partition_name); -- use this if you use role based permission
END IF;
    EXECUTE format('INSERT INTO %I ("OwnerId","DaddyTable","SaleId","RunId","CreateDateTime","SalesetId","Result","Score","NumberOfMatches" ) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9)', partition_name) 
    USING NEW."OwnerId",NEW."DaddyTable",NEW."SaleId",NEW."RunId",NEW."CreateDateTime",NEW."SalesetId",NEW."Result",NEW."Score",NEW."NumberOfMatches";

RETURN NULL;
END
$$
LANGUAGE plpgsql;

【问题讨论】:

    标签: postgresql function


    【解决方案1】:
        EXECUTE format(E'CREATE TABLE %I (CHECK ( date_trunc(\'day\', %I.CreateDateTime) >= ''%s'' AND date_trunc(\'day\',
    %I.CreateDateTime) < ''%s'')) INHERITS (myschema."Testoltpsaless")', 
        VARIADIC ARRAY [partition_name, start_of_month,end_of_next_month]); ```
    

    您的格式字符串中有五个格式说明符,但您只传递了三个参数。除非您使用位置格式,例如%1$I,您必须提供相同数量的参数,因为它们是按顺序使用的。

    https://www.postgresql.org/docs/current/functions-string.html#FUNCTIONS-STRING-FORMAT

    【讨论】:

    • 感谢您的及时回复,我已经查看了文档,需要一些帮助来理解前面执行格式命令中的五个格式说明符。您如何将其分解为 5 个说明符?
    • 你的字符串使用了 3 个%I 和 2 个%s,你需要为它们中的每一个提供一个参数,即使它们是同一个。例如。 format('%s%s%s%s%s', 'a', 'a', 'a', 'a', 'a') 制作 aaaaa。您不能只提供一个并在每个地方都使用它,除非您使用位置格式(无论如何我都这么称呼它),例如format('%1$s%1$s%1$s%1$s%1$s', 'a') - 告诉它在每一个上使用 arg 1。
    • 太棒了,感谢您的帮助,因为该功能现在可以按预期工作。今天又学到了一课!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2018-04-22
    • 1970-01-01
    • 2016-08-16
    相关资源
    最近更新 更多