如何使用 sqlplus 脚本中的 select max(colx) from tabley 返回的值填充替换变量?

Posted

技术标签:

【中文标题】如何使用 sqlplus 脚本中的 select max(colx) from tabley 返回的值填充替换变量?【英文标题】:how can you populate a substitution variable with the value returned by select max(colx) from tabley in sqlplus script? 【发布时间】:2019-12-09 19:46:21 【问题描述】:

我想将 select max(column) from mytable 返回的值放入使用 SQL*PLUS 运行的同一脚本中的多个后续 SQL 语句中,而不是在多个实例中执行 select max(column) from mytable脚本中的后续 SQL。有几种方法可以实现这一点,但能够定义一个替换变量,然后使用 select 语句设置它的值当然似乎是最简单和最清晰的编写方式,因为绑定变量似乎需要不同的编写风格,更高级别的复杂性,对于那些将来可能需要进行更改的人来说不太清楚。

【问题讨论】:

【参考方案1】:

没问题 - 使用变量。方法如下:

声明一个变量;使用exec 将值放入其中:

SQL> var max_deptno number;
SQL> exec select max(deptno) into :max_deptno from emp;

PL/SQL procedure successfully completed.

它包含什么?

SQL> print max_deptno

MAX_DEPTNO
----------
        30

在您拥有的那些后续选择中使用它:

SQL> select ename, job, sal from emp where deptno = :max_deptno;

ENAME      JOB              SAL
---------- --------- ----------
ALLEN      SALESMAN        1600
WARD       SALESMAN        1250
MARTIN     SALESMAN        1250
BLAKE      MANAGER         2850
TURNER     SALESMAN        1500
JAMES      CLERK            950

6 rows selected.

SQL> select * from dept where deptno = :max_deptno;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        30 SALES          CHICAGO

SQL>

【讨论】:

感谢您的信息。是的,这确实可以很好地为绑定变量赋值,但它本身并不能解决所有相关问题。尝试在 "create table mytable as select * from inp_table where columnx = :max_columnx" 中使用绑定变量失败,导致 "ORA-01027: bind variables not allowed for data definition operations" 。为了以最简单的方式解决这个问题,我在加载绑定变量值后插入了以下行:“define mymax = :max_columnx”。使用替换变量不会产生错误。 说得太早了。显然,绑定变量不能在“CREATE TABLE”中用作选择(DDL),当我执行“define var = bind_var”时,替换只是简单地替换回绑定变量,所以无论如何我都会得到 ORA-01027 错误。我可以只写 CREATE使用“WHERE Colx = (select max(colx) from table)”的表,但整个意图是用先前确定并存储的基本常量文字替换选择执行,以最大限度地减少资源利用率。 没错,绑定变量不能在 CREATE TABLE 中使用,这已经不是什么稀奇事了。一种解决方法 - 如果它是一个包含对相同值的许多引用的 .SQL 脚本 - 将使用某种 占位符,例如... where colx = PAR_MAXX 并且您将在编辑器中执行 replace all,将 PAR_MAXX 替换为(例如)6637(或任何值)。或者,切换到动态 SQL,但这无法扩展且难以维护。【参考方案2】:
SQL> var max_loaD_MONTH VARCHAR(20);
SQL> exec select max(LOAD_MONTH) into :max_LOAD_MONTH from CASETABLE;)

SQL> CREATE TABLE NEW_CASES AS SELECT * FROM CASETABLE WHERE ROWNUM < 1;

SQL> INSERT INTO NEW_CASES AS SELECT * FROM CASETABLE WHERE LOAD_MONTH = :max_load_month;

这允许我创建一个仅包含最近一个月的案例条目的表,并将所有其他案例条目放入另一个临时表 (where load_month != :max_load_month)。我需要这样做,因为案例表的更新运行了 20 多个小时,并且只将那些正在更新的记录放在临时表中,更新只需要 5 分钟,然后我可以使用 UNION ALL 之间的 UNION ALL 重新创建 casetable两个临时表。我认为这会起作用,但不想在更新查询中使用两次select max(load_month) - 似乎太多,无法为每条处理的记录获取 2019-11 格式的值。

感谢您的帮助。我仍然认为将select max(load_month)(即2019-11)的值分配给替换变量的方法是理想的。在 SQL Developer define max_load_month = (select max(load_month) from casetable) 中工作,但不是我希望的那样。似乎在 SQLDeveloper 中,它替换了查询,然后在使用变量的地方执行查询,而我原本打算将查询的值分配给 max_load_month 而不是查询。但是在 PL/SQL 中,由于查询格式错误,因此定义失败。

【讨论】:

我建议你熟悉markdown。我认为这将使您的帖子更易于阅读和理解。

以上是关于如何使用 sqlplus 脚本中的 select max(colx) from tabley 返回的值填充替换变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何将select的结果分配到sqlplus变量中

SQLPLUS如何使用编辑和保存一个sql脚本

SQLPlus:在脚本中使用特殊字符作为密码

sqlplus多行代码怎么

将文本格式化为数字的 SQLplus 脚本

如何忽略从 SQL Plus 运行的 SQL 脚本中的 & 符号?