如何使用 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 返回的值填充替换变量?的主要内容,如果未能解决你的问题,请参考以下文章