11

当我在and事务中有两个INSERTSQL 语句(见下文)时,则不会返回任何内容,但如果我取出并返回插入的记录。 我怎样才能在事务中工作?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;
4

2 回答 2

8

一种方法是使用数据修改 CTE并将两个INSERTs 打包到一个命令中。需要 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();
于 2012-09-17T17:04:12.260 回答
3

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

一个接一个地运行每个语句,它应该可以正常工作。我无法给出更详细的示例,因为您没有提到您使用的是哪种语言。

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

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,)]
于 2012-09-18T00:49:29.520 回答