在where子句中使用Oracle SQL变量时遇到问题

时间:2013-01-18 15:11:08

标签: sql oracle plsql oracle10g

我正在尝试编写一个脚本来帮助解决众多“这个动作列表中发生了什么”类型的调用,但是我正在做一些砖墙做一些最简单的操作。

我正在尝试声明一个变量并在查询的where子句中使用它。我已经删除了查询中不相关的所有内容,试图让这个核心功能正常工作。

id通常是一个18位数字,但偶尔会包含alpha-numerics,因此它为varchar。我试图将它与之比较的列是一个18字节的varchar字段。

declare
  id_to_check VARCHAR(18);  

begin
  id_to_check := '549576015500000109';

select 
  txn_timestamp, exception_type
from cut.event
where irn_id = id_to_check;

end;

每次抛出一个错误:'在这个select语句中需要一个INTO子句'。我理解INTO是如何工作的,即如果我想将select的结果赋给变量,但我不明白在这个实例中如何应用,因为我没有将查询的结果赋给变量? / p>

另一个令人沮丧的事情是我实际上正在关注docs.oracle.com上的文档。

http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/overview.htm#LNPLS001

我也查看了各种谷歌搜索结果,但我无法弄清楚如何在没有先选择内容的情况下与变量进行比较,但正如您所看到的,我无法选择进入因为我只有出于比较原因需要它吗?

亲切的问候, 伊恩

3 个答案:

答案 0 :(得分:3)

RaphaëlAlthaus的答案适用于你在PL / SQL中做的事情,但我不确定这实际上是你想要的。听起来你想要一个简单的SQL查询,但你想能够传递一个值吗?假设您在SQL * Plus或SQL Developer中运行它,您可以通过几种方式声明和使用固定值。 (类似的方法将在其他客户端可用; PL / SQL开发人员似乎喜欢这两种方法,至少在命令窗口中,但不确定Toad或其他任何东西)。

1)使用substitution variable

define id_to_check = 549576015500000109

select txn_timestamp, exception_type
from cut.event
where irn_id = '&id_to_check';

2)使用bind variable

variable id_to_check varchar2(18)

exec :id_to_check := '549576015500000109';

select txn_timestamp, exception_type
from cut.event
where irn_id = :id_to_check;

exec是一个小型匿名PL / SQL块的简写,但除了将值赋给变量的步骤之外,它是纯SQL,因此查询不需要包含在{{ 1}},您不必担心选择begin ... end变量。

在任何一种情况下,当运行脚本时,您可以拥有ID值passed as an argumentask for it as part of the script。例如,您可以编写into脚本:

query.sql

...并运行:

define id_to_check = &1

select txn_timestamp, exception_type
from cut.event
where irn_id = '&id_to_check';

......或作为:

sqlplus -l -s <user>/<password> @query 549576015500000109

...并提示用户在运行时输入ID。

答案 1 :(得分:1)

问题不是“你想把结果放到变量中吗。”

在Oracle过程的“正文”中,如果没有SELECT子句,则无法使用INTO

(事实上你可以拥有,但是在游标中)。

所以

declare
  id_to_check VARCHAR(18);
  event_timestamp cut.event.txn_timestamp%TYPE;
  event_exception cut.event.exception_type%TYPE;

begin
  id_to_check := '549576015500000109';

select 
  txn_timestamp, exception_type
  INTO event_timestamp, event_exception
from cut.event
where irn_id = id_to_check;

end;

警告:如果未找到任何结果,则会引发NO_DATA_FOUND异常。

您可以使用

进行管理
begin
  id_to_check := '549576015500000109';

  BEGIN
  select 
    txn_timestamp, exception_type
    INTO event_timestamp, event_exception
    from cut.event
    where irn_id = id_to_check;

   EXCEPTION WHEN NO_DATA_FOUND THEN 
   --...something
  END

end

答案 2 :(得分:0)

你真正的问题不是关于使用变量(你是否正确),而是关于从PL / SQL块返回游标。

你似乎相信在程序结束时的一个裸选择应该以某种方式使它返回结果或至少显示它们。虽然有些数据库的工作方式如此 - 但Oracle没有。如果您希望任何数据留下任何类型的块(如函数或过程),则必须明确地传递它们。通常这是通过使用游标ref类型的in参数来完成的。

正如您所看到的,没有into的select在Oracle中没有意义。即使您设法使其工作并选择数据,您也无法访问结果。