use*_*783 6 postgresql transaction ddl plpgsql
PostgreSQL newbie here trying to put together a transactional DDL script to atomically create a database and its schema in Postgres 9.3: in a transaction, create a few tables; if any errors, roll the whole thing back; otherwise commit. I'm having a hard time getting the syntax right, and I suspect my problems might stem from conflating SQL DDL with PL/pgSQL and/or not grokking the transaction semantics.
Long story short, what's the PL/pgSQL boilerplate for a script to do something like this?
My attempts have gone something like schema.sql
here:
BEGIN;
CREATE TABLE IF NOT EXISTS blah ( ... ); -- much DDL
EXCEPTION WHEN OTHERS THEN ROLLBACK; -- this, I gather, is PL/pgSQL
COMMIT;
Run Code Online (Sandbox Code Playgroud)
\i schema.sql
at the psql prompt produces a syntax error at or near EXCEPTION
. OK, so EXCEPTION
must be PL/pgSQL, and all this needs to go in a PL/pgSQL declaration. Let's try again:
Per the grammar at http://www.postgresql.org/docs/9.3/static/plpgsql-structure.html, this looks like:
[ <<label>> ]
[ DECLARE
declarations ]
BEGIN
statements
END [ label ];
Run Code Online (Sandbox Code Playgroud)
I don't need to name this, it's a one-off provisioning script, not declaring a function I'm going to use again. So skip the declarations and expand statements
to what I had before:
BEGIN
BEGIN;
CREATE TABLE IF NOT EXISTS blah ( ... ); -- much DDL
EXCEPTION WHEN OTHERS THEN ROLLBACK;
COMMIT;
END;
Run Code Online (Sandbox Code Playgroud)
This blows up in even worse fashion, with syntax errors on BEGIN
, EXCEPTION
, and then it keeps running the rest of the script anyways, complaining about not being in a transaction.
What's the misunderstanding I have here?
如果有任何错误,请回滚整个内容;
它比你想象的要简单。事务中的任何异常(未以某种方式捕获)都会自动触发ROLLBACK
整个事务的a 。你不需要做任何额外的事情。
BEGIN;
CREATE TABLE IF NOT EXISTS blah ( ... );
-- much more DDL
COMMIT;
Run Code Online (Sandbox Code Playgroud)
你不能启动,提交或回滚事务里面PLPGSQL可言,因为PLPGSQL块总是在外部事务的情况下自动运行。
不要将事务管理的 SQL 命令与plpgsql 代码块的元素混淆。BEGIN
两者都用作关键字,这是唯一的共同点。这绝不是模棱两可的,因为 SQL 命令在 plpgsql 代码中不可用,并且在 plpgsql 代码块之外没有 plpgsql 命令。
EXCEPTION
plpgsql 块中的子句仅用于捕获错误并在ROLLBACK
. 当然,只有做一些ROLLBACK
不会撤销的事情才有意义——比如提出一条永远不会回滚的消息。
您的演示代码不需要任何这些。
归档时间: |
|
查看次数: |
6934 次 |
最近记录: |