【问题标题】:Does Oracle support RETURNING in an SQL statement?Oracle 是否支持 SQL 语句中的 RETURNING?
【发布时间】:2021-04-08 09:45:06
【问题描述】:

PostgreSQL 支持 RETURNING 子句,例如

UPDATE some_table SET x = 'whatever' WHERE conditions RETURNING x, y, z

MSSQL 通过 OUTPUT 子句支持该语法的变体。

然而,Oracle“返回到”似乎打算在存储过程的上下文中将值放入变量中。

有没有一种方法可以在不涉及存储过程的情况下获得与上述 SQL 等效的 SQL 以在 Oracle 中运行?

注意:如果存在纯 SQL 解决方案,我正在寻找一种纯 SQL 解决方案,而不是一种特定于语言的解决方案,或者需要在代码中进行特殊处理。实际的 SQL 是动态的,调用的代码与数据库无关,只有 SQL 被调整。

【问题讨论】:

  • 你当然可以使用它,告诉 oracle 将 x,y,z 返回到 :a,:b,:c 中。你用的是什么编程语言?
  • Oracle 中的普通 SQL 不支持此功能,仅当您使用 PL/SQL 时(例如在存储过程中)
  • 您可以在JDBC中使用RETURNING INTO子句,即不用PL/SQL
  • @gsalem 这将需要使用返回参数,这使得它比常规游标/返回集更复杂,并且非常特定于 Oracle。实际的 SQL 是动态的,使用代码与数据库无关(只有 SQL 被调整以适应 DB,而不是代码)

标签: oracle sql-returning


【解决方案1】:

Oracle 不直接支持在 SELECT 语句中使用 DML 返回子句,但您可以通过使用 WITH 函数来伪装这种行为。虽然下面的代码使用了 PL/SQL,但该语句仍然是一个纯 SQL 语句,可以在任何可以运行常规 SELECT 语句的地方运行。

SQL> create table some_table(x varchar2(100), y number);

Table created.

SQL> insert into some_table values('something', 1);

1 row created.

SQL> commit;

Commit complete.

SQL> with function update_and_return return number is
  2      v_y number;
  3      --Necessary to avoid: ORA-14551: cannot perform a DML operation inside a query
  4      pragma autonomous_transaction;
  5  begin
  6      update some_table set x = 'whatever' returning y into v_y;
  7      --Necessary to avoid: ORA-06519: active autonomous transaction detected and rolled back
  8      commit;
  9      return v_y;
 10  end;
 11  select update_and_return from dual;
 12  /

UPDATE_AND_RETURN
-----------------
                1

不幸的是,这种方法存在重大限制,可能使其不适用于非平凡的案例:

  1. 必须在语句中提交 DML。
  2. WITH 函数语法需要 12.1 及更高版本的客户端和服务器版本。
  3. 返回多列或多行需要更高级的功能。多行将需要函数返回一个集合,并且语句的SELECT 部分将必须使用TABLE 函数。对于每个不同的结果集,多个列将需要一个新类型。如果幸运的话,您可以使用其中一种内置类型,例如SYS.ODCIVARCHAR2LIST。否则,您可能需要创建自己的自定义类型。

【讨论】:

    【解决方案2】:

    您可以在 SQL 中执行此操作,而不需要 pl/sql,这取决于您的工具和/或语言。下面是 sqlplus 中的一个例子:

    SQL> create table t0 as select * from dual;
    
    Table created.
    
    SQL> var a varchar2(2)
    SQL> update t0 set dummy='v' returning dummy into :a;
    
    1 row updated.
    
    SQL> print a
    
    A
    --------------------------------
    v
    

    【讨论】:

    • 抱歉,我的意思是 SQL 可以在单个命令/语句中发送,并且会返回一个正常的结果集(如 PostgreSQL、MSSQL、SQLite... 等)。
    猜你喜欢
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 2016-12-19
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多