1

我正在使用 PostgreSQL 服务器 9.0.4,我正在尝试 1. 创建一个新架构,2. 在该架构下创建一个表,以及 3. 在该表中插入数据,在同一个 EXECUTE 中并失败。如果我尝试

CREATE OR REPLACE FUNCTION pg_temp.test( ) 
    RETURNS void LANGUAGE plpgsql AS 
$BODY$  
BEGIN
    EXECUTE 'CREATE SCHEMA test; CREATE TABLE test.t (id integer ); 
INSERT INTO test.t (id) VALUES (0);';
END;
$BODY$;

select pg_temp.test( );

我因以下错误而失败。

ERROR:  schema "test" does not exist
LINE 1: ...t; CREATE TABLE test.t (id integer ); INSERT INTO test.t (id...
                                                             ^

但是,如果在同一个事务中使用两个 EXECUTE,同样的事情会起作用。

CREATE OR REPLACE FUNCTION pg_temp.test( ) 
    RETURNS void LANGUAGE plpgsql AS 
$BODY$  
BEGIN
    EXECUTE 'CREATE SCHEMA test; CREATE TABLE test.t (id integer );';
    EXECUTE 'INSERT INTO test.t (id) VALUES (0);';
END;
$BODY$;

无法理解两者的区别。如果有人可以在这里帮助我,将不胜感激。

谢谢。

4

3 回答 3

3

您错误地将多语句等同于交易。

整个函数在单个事务中运行。无论您做什么,都在一笔交易中。没有选项可以在 PL/PgSQL 函数内自动提交或回滚(无论如何,在 Pg 9.3 或更早版本中,如果您正在阅读本文并在较新版本上,请检查)。

多语句通常不是一个好主意。如果它们包含 DDL,则更是如此,因为在解析时尚未执行较早的语句。

只需使用两个EXECUTE语句。在这里使用多语句没有任何好处。

(顺便说一句,您使用的是 PostgreSQL 9.0.4。紧急升级,您的版本有一些重大错误修复和关键安全修复。升级到 9.0.13 是安全的,请参阅版本政策。)

于 2013-08-29T23:22:06.027 回答
1

克雷格的答案非常接近。我在 postgresql 邮件列表中的帖子中得到了更多详细信息。看到这个

总结一下,

  1. 要执行的字符串中的所有子语句在执行它们之前都会被解析。因此,INSERT 的解析失败,因为此时模式不存在。
  2. CREATE TABLE,作为一个实用程序语句没有被严格解析并且工作正常。但是,此行为是特定于实现的,并且可能会因版本而异。

更远,

最好避免尝试在一个查询字符串中执行多个语句,特别是如果它们中的任何一个是 DDL

于 2013-09-01T04:21:34.960 回答
-1

您必须将其分开运行,单行不提交因此从我的角度来看没有创建方案解决方案

CREATE OR REPLACE FUNCTION pg_temp.test( ) 
    RETURNS void LANGUAGE plpgsql AS 
$BODY$  
BEGIN
    EXECUTE 'CREATE SCHEMA test'; 
    EXECUTE 'CREATE TABLE test.t (id integer )'; 
EXECUTE 'INSERT INTO test.t (id) VALUES (0);';
END;
$BODY$;
select pg_temp.test( );
于 2013-08-29T22:53:02.500 回答