在相同的EXECUTE中创建新的模式,表和插入数据

时间:2013-08-29 22:17:30

标签: postgresql insert schema plpgsql execute

我正在使用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$;

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

感谢。

3 个答案:

答案 0 :(得分:3)

您错误地将多语句等同于事务。

整个函数在单个事务中运行。无论你做什么都是在一次交易中。没有选项可以在PL / PgSQL函数内自动提交或回滚(无论如何,如果您正在阅读此版本和更新的版本,请检查)。

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

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

(顺便说一下,你在使用PostgreSQL 9.0.4。紧急升级,你的版本有一些主要的错误修复和a critical security fix。升级到9.0.13是安全的,请参阅version policy。 )

答案 1 :(得分:1)

克雷格的答案非常接近。我在postgresql邮件列表中回复了我的帖子,得到了更多细节。见this

总结一下,

  1. 在执行任何子语句之前,将解析要执行的字符串中的所有子语句。因此,INSERT的解析失败,因为此时架构不存在。
  2. CREATE TABLE,作为一个实用程序语句没有严格解析并且工作正常。但是,此行为是特定于实现的,可能会在发行版之间发生变化。
  3. 此外,

      

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

答案 2 :(得分:-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( );