在SQL Plus中使用绑定变量有多个行返回?(Using bind variables in SQ

2019-09-18 09:47发布

这是一个愚蠢的问题,但我似乎无法避开它。 我这是造成在OCI程序麻烦的查询,所以我想在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和工会不那么顺利走在一起):

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)

Answer 1:

类似@格伦的方法,但你可以在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也工作(当作为脚本运行)。 我觉得这是运行在SQL更容易从PRO * C文件复制到的已使用:结合的形式,纯粹是因为你没有在所有修改代码。


顺便说一句,你可以这样写:

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)


Answer 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);


文章来源: Using bind variables in SQL Plus with more than one row returned?