我有这样的程序...
declare
v_psg varchar2(10);
id_no number;
begin
select value into v_psg from settings_am where key = 'PSG';
select id into id_no from product where to_char(psg) in (v_psg);
end;`
从select value into v_psg from settings_am where key = 'PSG';
返回的值为
“ 1”,“ 2”,“ 3”
当我运行此过程时,返回ora错误-ORA-01403。
请告知我应如何将v_psg值传递给产品表的psg列?
答案 0 :(得分:1)
如果您有ORA-01403
,则表示您很幸运。这是NO_DATA_FOUND
错误,这意味着一个(可能是第一个)查询未返回任何内容。
这两个语句可以合并为
select id
from product
where to_char(psg) in (select value
from settings_am
where key = 'PSG'
);
为什么要先选择value
,然后在另一个查询中使用它?此外,它根本行不通。 v_psg
被声明为VARCHAR2
变量。按照您描述的方式,它包含以下字符串:'1','2','3'
,就像您所拥有的一样:
SQL> create table settings_am (key varchar2(10),
2 value varchar2(20)); --> note size here
Table created.
SQL> insert into settings_am (key, value)
2 values ('PSG', q'['1','2','3']');
1 row created.
SQL> select * From settings_am;
KEY VALUE
---------- --------------------
PSG '1','2','3'
SQL>
如您所见,尽管您声明的变量为value
,但我扩大了10
列的大小。为什么?由于
SQL> select length(value) from settings_am where key = 'PSG';
LENGTH(VALUE)
-------------
11
即您不能将长度为 11 的东西放入长度为 10 的东西。
或者,如果您的数据实际上包含PSG
键的3行,那么这些值是否已经用单引号引起来了?如果是这样,那很奇怪;人们通常不这样做。无论如何,假设您成功地将字符串'1,2,3'
(我认为您实际拥有的)获取到VARCHAR2
变量中,那么您必须将其拆分为若干行才能在其中使用IN
子句:
SQL> create table product (id number, psg varchar2(10));
Table created.
SQL> insert into product (id, psg) values (100, '1');
1 row created.
SQL> insert into product (id, psg) values (200, '2');
1 row created.
SQL>
然后进行查询(第3-5行代表将字符串拆分为行):
SQL> select p.id
2 from product p
3 where p.psg in (select regexp_substr('&&v_psg', '[^,]+', 1, level)
4 from dual
5 connect by level <= regexp_count('&&v_psg', ',') + 1
6 );
Enter value for v_psg: 1,2,3
ID
----------
100
200
所以,使用起来会不会更简单
SQL> select id
2 from product
3 where to_char(psg) in (select value
4 from settings_am
5 where key = 'PSG'
6 );
ID
----------
100
200
SQL>
请注意,这两个选项还显示了您的查询错误的原因:当您遇到id_no number;
错误时,不能将两个值(行)放入声明为TOO_MANY_ROWS
的变量中。
最后,您想做什么?您要解决什么问题?显然,除了特殊情况(每个值仅一行)之外,您的查询无法正常工作。如果您可以提供测试用例(创建表并插入到示例数据中)以及预期的输出,那么对您的帮助会更容易。