如何在plsql中将字符串数据类型传递给数字数据类型

时间:2019-06-30 08:10:22

标签: sql oracle plsql ora-01722 ora-01403

我有这样的程序...

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列?

EDIT - Tried with test case suggested

1 个答案:

答案 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的变量中。


最后,您想做什么?您要解决什么问题?显然,除了特殊情况(每个值仅一行)之外,您的查询无法正常工作。如果您可以提供测试用例(创建表并插入到示例数据中)以及预期的输出,那么对您的帮助会更容易。