繁体   English   中英

从事务中的RETURNING *获取值

[英]Get values from RETURNING * within a transaction

当我在一个begin;内有两个INSERT SQL语句(见下文)时begin; commit; 事务然后RETURNING *不返回任何东西,但如果我取出begin; commit; RETURNING *确实返回插入的记录。
如何让RETURNING *在交易中运作?

BEGIN;

INSERT INTO gis_field_configuration
   (level_unique_name, level_name_caption, use_for_charts, use_as_displayby, 
    displayby_label, data_type, level_help_text)
VALUES (
    '[john].[john]',
    'john',
    'false',
    'false',
    '',
    'text',
    'help text'
);

INSERT INTO gis_field_configuration_bycube
   (cube, level_unique_name)
VALUES (
    'Instruments',
    '[john].[john]'
) RETURNING *;

COMMIT;

一种方法是使用数据修改CTE并将两个INSERT打包成一个命令。 需要PostgreSQL 9.1或更高版本:

WITH x AS (
   INSERT INTO gis_field_configuration (level_unique_name, level_name_caption
                ,use_for_charts, use_as_displayby, displayby_label, data_type
                ,level_help_text)
   VALUES (
       '[john].[john]',
       'john',
       'false',
       'false',
       '',
       'text',
       'help text'
   )
   )
INSERT INTO gis_field_configuration_bycube
   (cube, level_unique_name)
VALUES (
    'Instruments',
    '[john].[john]'
    )
RETURNING *;

但是,在任何情况下,您可以使用RETURNING *获取值。 只需发送COMMIT 之前读取它们。 作为批处理发送,如果将所有命令作为一个批处理发送,则仅返回last命令的结果 - 这将是COMMIT的结果。

阻止COMMIT; 直到你收到第二次INSERT的结果。


在plpgsql函数中

函数自动在事务内部运行。 您不需要显式BEGIN / COMMIT。 要重用值,您将从INSERT返回使用RETURNING *expressions* INTO [STRICT] *target*

考虑这个简单的演示:

CREATE TABLE foo (foo_id serial, bar text);

CREATE OR REPLACE FUNCTION f_foo()
  RETURNS void LANGUAGE plpgsql AS
$BODY$
DECLARE
   foo_var foo; -- type name = table name, fits return type of RETURNING *
   -- or use a generic type record
BEGIN

   INSERT INTO foo (bar)
   VALUES ('baz')
   RETURNING *
   INTO foo_var;

   RAISE NOTICE 'New id is: %', foo_var.foo_id;

   -- do stuff with foo_var

   END;
   $BODY$;

SELECT f_foo();

我怀疑您将所有这些语句作为语言客户端驱动程序中的单个文本字符串运行。 如果是这种情况,返回给客户端的结果将是您发送的语句块中的最后一个语句返回的结果。 在这种情况下,这是COMMIT语句,没有结果,所以你没有得到任何结果。

逐个运行每个语句,它应该工作正常。 我不能给出一个更详细的例子,因为你没有提到你正在使用哪种语言。

这是一个Python / psycopg示例。 当我尝试获取结果时,在一个blob中发送所有SQL的第一种方法会导致异常,因为commit不会产生结果。 第二个例子,我分别运行每个语句并在commit之前获取select的结果,工作正常。

import psycopg2

conn = psycopg2.connect("dbname=regress")
curs = conn.cursor();

# All in one blob
try:
    curs.execute("BEGIN; SELECT generate_series(1,10); COMMIT;")
    print(curs.fetchall())
except (psycopg2.ProgrammingError) as ex:
    print("Failed: ", ex)

# vs one-by-one
curs.execute("BEGIN;")
curs.execute("SELECT x.* FROM generate_series(1,10) x;")
print(curs.fetchall())
curs.execute("COMMIT;")

输出:

$ python3 test.py 
Failed:  no results to fetch
[(1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,), (10,)]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM