【问题标题】:How to use EXECUTE FORMAT ... USING in postgres function如何在 postgres 函数中使用 EXECUTE FORMAT ... USING
【发布时间】:2012-12-13 11:14:50
【问题描述】:
CREATE OR REPLACE FUNCTION dummytest_insert_trigger()
  RETURNS trigger AS
$BODY$
DECLARE
v_partition_name    VARCHAR(32);
        BEGIN
        IF NEW.datetime IS NOT NULL THEN
                v_partition_name := 'dummyTest';            
                EXECUTE format('INSERT INTO %I VALUES ($1,$2)',v_partition_name)using NEW.id,NEW.datetime;              
                END IF;                    
           RETURN NULL;
        END;
        $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION dummytest_insert_trigger()
  OWNER TO postgres;

我正在尝试使用 插入 dummyTest 值(1,'2013-01-01 00:00:00+05:30');

但它显示错误为

ERROR: function format(unknown) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Context: PL/pgSQL function "dummytest_insert_trigger" line 8 at EXECUTE statement

我无法得到错误。

【问题讨论】:

  • 您使用的是哪个版本的 PostgreSQL? AFAIK,format 函数是在 9.1 中添加的。

标签: postgresql format execute using


【解决方案1】:

您的函数在 Postgres 9.0 或更高版本中可能如下所示:

CREATE OR REPLACE FUNCTION dummytest_insert_trigger()
  RETURNS trigger AS
$func$
DECLARE
   v_partition_name text := quote_ident('dummyTest');  -- assign at declaration
BEGIN
   IF NEW.datetime IS NOT NULL THEN
      EXECUTE 
      'INSERT INTO ' || v_partition_name || ' VALUES ($1,$2)'
      USING NEW.id, NEW.datetime;              
   END IF;                    

   RETURN NULL;  -- You sure about this?
END
$func$  LANGUAGE plpgsql;

关于RETURN NULL

我建议不要使用混合大小写标识符。使用format( .. %I ..)quote_ident(),您将获得一个名为"dummyTest" 的表,您必须在它的其余部分使用双引号。相关:

改用小写:

quote_ident('dummytest')

只要您有一个静态表名,就没有必要将动态 SQL 与 EXECUTE 一起使用。但这可能只是简化的示例?

【讨论】:

  • :: 是的。这是一个简化的示例。实际上,我正在使用数据库分区来动态生成该表名,但它仍然不适用于更简单的部分。我在 postgres 9.1 上使用了小写的 dummytest,我收到以下错误错误:超出堆栈深度限制提示:在确保平台的堆栈深度限制足够之后,增加配置参数“max_stack_depth”(当前为 2048kB)。上下文:SQL 语句“INSERT INTO dummytest VALUES ($1,$2)”PL/pgSQL 函数“dummytest_insert_trigger”第 7 行在 EXECUTE 语句
  • @mona:听起来您可能正在使用触发器创建无限循环。避免这种情况是你的责任。
  • @ Erwin Brandstetter:是的,这是我的错误。感谢您的解决方案有效。 :) :)
  • 这太完美了。“只要你有一个静态表名,使用带有 EXECUTE 的动态 SQL 真的没有意义。”。
【解决方案2】:

您需要显式转换为text

EXECUTE format('INSERT INTO %I VALUES ($1,$2)'::text ,v_partition_name) using NEW.id,NEW.datetime;

【讨论】:

  • 是的。我遇到了问题。这只是由于版本引起的。我使用的是 9.0 版。谢谢
  • @mona:升级后:不需要强制转换为texttext 是引用文字的默认类型。
猜你喜欢
  • 2015-02-01
  • 1970-01-01
  • 2019-06-28
  • 1970-01-01
  • 2017-01-05
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多