在Select语句中声明和设置变量

23

我正试图编写一个简单的查询,在其中声明一些变量,然后在Oracle中的select语句中使用它们。我之前在 SQL Server 中能够使用以下语句完成:

DECLARE @date1   DATETIME
SET @date1 = '03-AUG-2010'

SELECT U.VisualID
FROM Usage u WITH(NOLOCK)
WHERE U.UseTime > @Date1

经过我的搜索,看起来你不能在Select语句中声明和设置变量。这是正确的吗?还是我遗漏了什么?

5个回答

16

我查了一些资料,似乎在Select语句中不能声明和设置变量。这是正确的吗?还是我漏掉了什么?

在Oracle PL/SQL和SQL中,有两种不同的语言和引擎。您可以在PL/SQL中嵌入SQL DML,从而获得变量。例如下面的匿名PL/SQL块。请注意,结尾处的/不是PL/SQL的一部分,而是告诉SQL*Plus发送前面的块。

declare 
    v_Date1 date := to_date('03-AUG-2010', 'DD-Mon-YYYY');
    v_Count number;
begin
    select count(*) into v_Count
    from Usage
    where UseTime > v_Date1;
    dbms_output.put_line(v_Count);
end;
/

问题在于,与您的T-SQL代码等效的块不起作用:

SQL> declare 
  2      v_Date1 date := to_date('03-AUG-2010', 'DD-Mon-YYYY');
  3  begin
  4      select VisualId
  5      from Usage
  6      where UseTime > v_Date1;
  7  end;
  8  /
    select VisualId
    *
ERROR at line 4:
ORA-06550: line 4, column 5:
PLS-00428: an INTO clause is expected in this SELECT statement

要将查询结果从PL/SQL(无论是匿名块、存储过程还是存储函数)传递到调用程序中,必须声明、打开并返回一个游标。 (超出了回答此问题的范围。 编辑:请参见从Oracle存储过程获取结果集

连接到数据库的客户端工具可能具有自己的绑定变量。在SQL*Plus中:

SQL> -- SQL*Plus does not all date type in this context
SQL> -- So using varchar2 to hold text
SQL> variable v_Date1 varchar2(20)
SQL>
SQL> -- use PL/SQL to set the value of the bind variable
SQL> exec :v_Date1 := '02-Aug-2010';

PL/SQL procedure successfully completed.

SQL> -- Converting to a date, since the variable is not yet a date.
SQL> -- Note the use of colon, this tells SQL*Plus that v_Date1
SQL> -- is a bind variable.
SQL> select VisualId
  2  from Usage
  3  where UseTime > to_char(:v_Date1, 'DD-Mon-YYYY');

no rows selected

请注意,上述内容是在SQLPlus中的,可能无法(很可能不会)在Toad PL/SQL Developer等其他工具中使用。以variable和exec开头的行是SQLPlus命令,而不是SQL或PL/SQL命令。因为表格为空,所以没有选定任何行。


3

我尝试过这个方法,它有效:

define PROPp_START_DT = TO_DATE('01-SEP-1999')

select * from proposal where prop_start_dt = &PROPp_START_DT

 


2

SET 命令是 TSQL 特定的 - 这里是与你发布的等价的 PLSQL:

v_date1 DATE := TO_DATE('03-AUG-2010', 'DD-MON-YYYY');

SELECT u.visualid
  FROM USAGE u 
 WHERE u.usetime > v_date1;

不需要在变量前加“@”前缀;我倾向于在变量前加“v_”前缀以区分变量和列等。

参见此帖子有关于Oracle等效的NOLOCK...


0

我也是从SQL Server转来的,这个问题真的很烦人。对于那些使用Toad Data PointToad for Oracle的人来说,这非常简单。只需在变量名前面加上冒号,Toad就会提示打开一个对话框,在执行时输入值。

SELECT * FROM some_table WHERE some_column = :var_name;

0

我基本上想设置一个日期值(或VARCHAR2值),然后在选择语句中引用它。我认为TO_DATE更像是将字符串转换为Oracle日期的函数。 - Matthew Hoenstine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接