声明变量并在查询 oracle 中使用它们
Posted
技术标签:
【中文标题】声明变量并在查询 oracle 中使用它们【英文标题】:Declare variables and use them in query oracle 【发布时间】:2020-10-10 11:43:37 【问题描述】:我正在进行数据迁移,在 oracle 11g 中转换 Sybase 查询 从过去 2 天开始,我一直坚持这件事
@Declare @myDate Datetime
Select @myDate = workingDate from MyTable
然后很少有 sql 语句在 where 子句中使用变量 myDate
前任
Select * form table1
join table1 on table1.id = table.id
join table1 on table1.id = mytable.id
where mytable.workingDate = my_date
// 所以最后我想要声明一个变量,该变量将从 select 子句中获取其值,并在复杂查询中的进一步 sql 语句中使用它
我想在 Oracle 11g 中实现同样的目标,而不会增加任何复杂性
我是 Oracle 新手,需要您的帮助。
【问题讨论】:
可能类似这样:***.com/a/40360471/230471 结果将如何使用?对于数据迁移,您能否在不依赖 SQL*Plus 功能的情况下用 PL/SQL 编写整个内容? @WilliamRobertson 我正在寻找在 oracle 中声明 Sybase 的简单转换,我想在多个 where 子句中进一步使用 my_date 结果将如何使用?您只是要运行 SQL*Plus 脚本并让它打印出一些结果吗?或者既然你提到了迁移,会有insert into x select from y
类型的逻辑吗?如果是这样,您可以在 PL/SQL 中完成所有操作,并且不需要任何 variable
或 print
等。
我们没有足够的上下文信息您是否只想使用 SQL 和匿名 PL/SQL 转换 SQL 脚本或您是否希望将 Transact-SQL 转换为 PL/ SQL 过程、函数和包?
【参考方案1】:
您使用的是 SQLPlus:我认为您不能声明 SQLPlus TIMESTAMP 变量。
尝试使用 VARCHAR2 变量并转换为 TIMESTAMP:
SQL> select banner from v$version where rownum=1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
SQL> variable ko timestamp;
Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
NVARCHAR2 (n) | CLOB | NCLOB | BLOB | BFILE
REFCURSOR | BINARY_FLOAT | BINARY_DOUBLE ] ]
SQL> --
SQL> variable my_date varchar2(50) ;
SQL> begin
2 select workingDate into :my_date from MyTable;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL> print my_date;
MY_DATE
------------------------------
20-JUN-20 10.55.55.264286 AM
SQL> print :my_date;
MY_DATE
------------------------------
20-JUN-20 10.55.55.264286 AM
SQL> --
SQL> select * from mytable;
WORKINGDATE
------------------------------
20-JUN-20 10.55.55.264286 AM
SQL> select workingDate from MyTable where workingDate = to_timestamp(:my_date, 'DD-MON-YY HH.MI.SSXFF AM');
WORKINGDATE
------------------------------
20-JUN-20 10.55.55.264286 AM
SQL>
【讨论】:
我正在使用 sql developer,这个 sql 脚本是从 java code hibernate 调用的 我不知道hibernate,也不知道它是调用SQLPlus还是只能执行SQL和PL/SQL语句。 它执行 sql 和 pl/sql 但是上面的事情在 sql 中是可能的? 它是 SQL,但它只能由 SQL*Plus 执行。 @Shelly - 你应该知道什么将在 SQL Developer 中运行,什么将在 SQL*Plus 中运行以及你可以从 Hibernate 中调用什么是三种不同的东西。您可能会花费大量时间让 SQL*Plus/SQL Developer 脚本按照您的意愿运行,然后发现它在 Hibernate 中没有用,您必须重新开始。【参考方案2】:variable
不支持日期或时间戳。此外,您的最终查询应使用:my_date
(表示主机变量),而不是my_date
。
如果目标是使用在上一步中填充的变量来填充表,您可以对整个任务使用 PL/SQL,例如
declare
myDate date;
begin
select some_col into myDate from wherever;
insert into target_table (col1, col2, col2)
select x, y, z
from source_table
where business_date = myDate;
end;
或者更好的是,定义PL/SQL packages 来封装您的处理逻辑。
关于您发布的代码,从 Oracle 12.1 开始,您可以在 PL/SQL 中声明一个引用游标,并让 SQL*Plus 等客户端简单地调用该块并打印结果:
declare
my_date timestamp;
results sys_refcursor;
begin
select systimestamp into my_date
from dual;
open results for
select my_date as my_date from dual;
dbms_sql.return_result(results);
end;
/
PL/SQL procedure successfully completed.
ResultSet #1
MY_DATE
---------------------------------------------------------------------------
20-JUN-20 10.02.29.130000000
1 row selected.
对于早期的 Oracle 版本,您仍然需要在 SQL*Plus 中将 ref 游标声明为宿主变量:
set autoprint on
var results refcursor
declare
my_date timestamp;
begin
select systimestamp into my_date
from dual;
open :results for
select my_date as my_date from dual;
end;
/
(或set autoprint off
,然后明确print results
。)
虽然我不懂 Java,所以我不知道上述任何方法是否适用于您的环境。
【讨论】:
以上是关于声明变量并在查询 oracle 中使用它们的主要内容,如果未能解决你的问题,请参考以下文章