2

这是一个愚蠢的问题,但我似乎无法解决它。我有一个在 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 和 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 - 64 位,在 Red Hat Enterprise Linux ES 版本 4 (Nahant Update 8) 上运行

4

2 回答 2

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)
于 2012-06-22T13:53:11.427 回答
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);
于 2012-06-22T13:33:38.077 回答