在过程中重复使用 Select 语句

Reuse Select Statement within a Procedure

我喜欢做类似的事情

create tmp_table as ( select 1 some_value, 2 some_other_value from dual union select 3 some_value, 4 some_other_value from dual );

insert into table1 (field1) select some_value from tmp_table;

update table2 set field2 = 5 where field1 in ( select some_value from tmp_table );

drop tmp_table;

有更好的方法吗?也许是 WITH 语句的迭代使用?

with tmp_statement as (select ...) ( insert... update ... )

编辑:

您好,很抱歉提出一个非常笼统的问题。基本上,我想改进一些公司语法(select..loop...在这里逐行慢慢地做事)通过拆分操作但保持“一个 select only”规则有效,因为select 会很庞大,无论如何您只想编辑一个 select。我尝试使用 with 因为它看起来更接近现有语法。但也许将 select 加载到 temp/private/actual table 中的功能是更好的方法。

谢谢大家!

如果您正在寻找一种纯粹的 SQL 解决方案来跨多个语句引用一个值,请使用替换变量(适用于 SQL*Plus,SQL Developer, sqlcl 和任何其他支持 SQL*Plus 命令的环境):

ACCEPT some_value PROMPT "Please enter a value for SOME_VALUE:"

insert into table1 (field1) select '&&some_value' from dual;

update table2 set field2 = 5 where field1 in ('&&some_value' );

但是,您对 set-based 操作的使用表明您期望 TMP_TABLE 可能包含不止一行。以上在那种情况下不起作用。如果是这种情况,请编辑您的问题以提供有关您要实现的目标的更多详细信息。

对此有多种解决方案,其中包括 PL/SQL 集合或跨执行保留 TMP_TABLE。这取决于你想多久做一次。

创建和删除像 TMP_TABLE 这样的对象的 anti-pattern 在具有 T-SQL 背景的开发人员中很常见。 Oracle 在几个方面与 SQL Server 不同,这就是其中之一:作为某些事务逻辑的一部分,它不赞成动态执行 DDL。

可能您需要的方法是将 TMP_TABLE 创建为全局临时 TABLE。这是一个永久数据结构,但它的数据在事务(或会话)结束时被丢弃。如果您选择这种方法,您将创建 TMP_TABLE 一次,然后在需要时使用它,而不会在每个会话结束时删除。 Find out more.

如果您使用的是 Oracle 18c 或更高版本,您可以使用新的 private temporary tables

在您的特定情况下,您可以创建私有 table,然后进行插入和更新、提交和退出。私有临时 table 可以是特定于事务或特定于会话的。

考虑参数 PRIVATE_TEMP_TABLE_PREFIX 的值,它决定了名称约定的前缀

create private temporary table ora$ptt_tmp_table on commit drop definition 
as select 1 as some_value from dual  ;          

insert into table1 (field1) select some_value from ora$ptt_tmp_table  ;

update table2 set field2 = 5 where field1 in ( select some_value from  ora$ptt_tmp_table  );

commit ; -- here the private table is dropped automatically

您没有发布足够的详细信息,所以我会尝试列出所有变体:

  1. 如果您只需要几个变量,那么您有以下选择:

    • 替换变量 (&var)
    • PL/SQL 变量,不同的可用范围,例如局部变量,私有或 public 包变量,甚至 objects
    • Collections:嵌套tables或varrays,例如:
      • 变量数组:select * from table(sys.odcivarchar2list('a','b','c'));
      • 嵌套 table:select * from table(sys.ku$_vcnt('a','b','c'));
      • 嵌套 table 个数字对:
select * 
from
 table(
   sys.ku$_objnumpairlist(
         ku$_objnumpair(1,2),
         ku$_objnumpair(3,4)));
      NUM1       NUM2
---------- ----------
         1          2
         3          4
  • 上下文变量,例如:
SQL> call DBMS_SESSION.SET_CONTEXT('CLIENTCONTEXT', 'var1', 'value1');

Call completed.

SQL> select SYS_CONTEXT('CLIENTCONTEXT', 'var1') as var1 from dual;

VAR1
-----------------
value1
  1. 如果需要存储数据集(行集):
  • 全局临时tables(甚至私有临时表(18c+))
  • Collections