2012-06-22 25 views
2

这是一个愚蠢的问题,但我似乎无法绕过它。我有一个查询在OCI程序中造成麻烦,所以我想在SQL * Plus中手动运行它来检查是否有任何区别。这是查询:在SQL Plus中使用绑定变量并返回多行?

select e.label as doc_name, 
         e.url, 
         i.item_id, 
         'multi' as form_type 
       from cr_items i, cr_extlinks e 
       where i.parent_id = :comment_id 
       and e.extlink_id = i.item_id 
       UNION 
       select null as doc_name, 
         utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
         r.item_id, 
         'single' as form_type 
       from cr_revisions r 
       where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual); 
end; 

我想给COMMENT_ID绑定到值3052753,所以我做了以下内容:

DECLARE 
    comment_id number := 3052753; 
    BEGIN 
    select e.label , 
          e.url, 
          i.item_id, 
          'multi' 
        from cr_items i, cr_extlinks e 
        where i.parent_id = :comment_id 
        and e.extlink_id = i.item_id 
        UNION 
        select null , 
          utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
          r.item_id, 
          'single' 
        from cr_revisions r 
        where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual); 
    END; 
/

这给这个错误:

ORA-06550: line 4, column 1: 
PLS-00428: an INTO clause is expected in this SELECT statement 

现在,我已经很不高兴了,因为我不想从根本上改变这个查询,但是无论如何我都奋不顾身,想出了这个(INTO和UNION不会如此顺利地走在一起):

DECLARE 
comment_id number := 3052753; 
x_label VARCHAR2(50); 
x_url VARCHAR2(500); 
x_item number; 
x_thing VARCHAR2(50); 
BEGIN 
select label, url, item_id, thing into x_label, x_url, x_item, x_thing from (
select e.label , 
         e.url, 
         i.item_id, 
         'multi' as thing 
       from cr_items i, cr_extlinks e 
       where i.parent_id = :comment_id 
       and e.extlink_id = i.item_id 
       UNION 
       select null , 
         utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
         r.item_id, 
         'single' as thing 
       from cr_revisions r 
       where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual)) ; 
END; 
/

但现在,当然是因为我返回超过1行,我得到的是完全可预测现在

ORA-01422: exact fetch returns more than requested number of rows 

,我可以继续,并开始使用光标等,但我的小查询越来越歪曲了原来的自我。我想要做的只是检查查询是否与comment_id的值一致。当然,我可以将comment_id硬编码到查询中,并且工作正常。但它在OCI中也能正常工作,所以我要在SQL * PLus中重现我在OCI代码中看到的绑定变量的问题。但是为什么在SQL * Plus中这样做很困难呢?我错过了真正明显的东西吗?

数据库是Oracle 10.2.0.1.0 - 在Red Hat企业版Linux ES版本4上运行64位(Nahant更新8)

回答

3

与@Glenn的方法类似,但您可以在SQL * Plus中声明一个绑定变量,并在普通的SQL查询中使用它。先用var[iable]命令声明:

variable comment_id number; 

然后用exec[ute]命令,它本质上是一个匿名块设置:

execute :comment_id := 3052753; 

然后用:comment_id引用运行原来的查询,并没有BEGINEND

select e.label as doc_name, 
         e.url, 
         i.item_id, 
         'multi' as form_type 
       from cr_items i, cr_extlinks e 
       where i.parent_id = :comment_id 
       and e.extlink_id = i.item_id 
       UNION 
       select null as doc_name, 
         utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
         r.item_id, 
         'single' as form_type 
       from cr_revisions r 
       where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual); 

我不认为有太多的功能差异下注除了个人偏好之外,两种方法都可以在SQL Developer中工作(当作为脚本运行时)。运行从已使用:绑定表格的Pro * C文件复制的SQL时,我发现这更容易,纯粹是因为您根本不必修改代码。


顺便说一句,你可以写:

where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual) 

没有额外select,如:

where r.revision_id = content_item.get_latest_revision(:comment_id) 
+0

感谢Alex,我已经试过了,但是它给出了与我自己的方法相同的错误:PLS-00428:在此SELECT语句中预计会出现INTO子句 – TrojanName

+1

您无法获得来自普通SQL块的PL/SQL错误;你正在运行你的查询*而没有* BEGIN' /'END',对吗? –

+0

不错。这就说得通了。 – Glenn

2

而不是创建一个匿名块,你可能要定义在sqlplus环境变量:

DEFINE comment_id = 3052753 

然后参考& comment_id在您的查询中。

select e.label as doc_name, 
         e.url, 
         i.item_id, 
         'multi' as form_type 
       from cr_items i, cr_extlinks e 
       where i.parent_id = &comment_id 
       and e.extlink_id = i.item_id 
       UNION 
       select null as doc_name, 
         utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
         r.item_id, 
         'single' as form_type 
       from cr_revisions r 
       where r.revision_id = (select content_item.get_latest_revision(&comment_id) from dual); 
+0

卫生署,我这样一个工具,我知道,在15年前!非常简单,我只是深入挖掘每一步。谢谢! :-) – TrojanName

+0

它应该只是:DEFINE comment_id = 3052753 – TrojanName

+0

谢谢,我现在纠正了(我从上面的匿名块剪切和粘贴)。 – Glenn