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

Posted

技术标签:

【中文标题】如何在plsql中将字符串数据类型传递给数字数据类型【英文标题】:How to pass string data type to number datatype in plsql 【发布时间】:2019-06-30 08:10:22 【问题描述】:

我有这样的程序...

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

【问题讨论】:

至少,您的一条 SQL 语句无法从相关表中找到它要查找的内容。考虑对 no_data_found 异常应用异常处理。 不相关,但是:to_char(psg) 毫无意义,因为 psg 列已经是 varchar 不,不是,表设置中的列值是 varchar2,其中表产品中的列 psg 是数字。 【参考方案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 错误。


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

【讨论】:

您准备的数据看起来绝对没问题,但是当我尝试在“in”语句select * from product where to_char(id) in (select value from settings_am where key = 'PSG') 下传递查询时,它返回“0”行。我使用正则表达式返回了结果,但我正在寻找更好的解决方案,因此发布了这个问题。虽然我看到为您返回的结果带有测试数据,但不确定为什么返回 0 行。 正如我所说:准备测试用例。同时,检查value 数据类型。如果是CHAR,请注意它的右侧填充了空格,直到它的全长,所以你可能需要trim(value) 您构建的测试用例非常好,所以我自己没有编造任何东西。此外,我复制粘贴了用于创建表/选择语句的脚本,并观察到返回 0 行,其中预期结果为 2 行。 我知道我的测试用例没问题。我感兴趣的是你的数据 我的数据是您的测试用例的精确副本,无论如何都没有区别。话虽如此,我已经使用了您的测试用例,但仍然没有得到与您相同的结果。我已经编辑了我的帖子并添加了一张图片供您理解。

以上是关于如何在plsql中将字符串数据类型传递给数字数据类型的主要内容,如果未能解决你的问题,请参考以下文章

如何在plsql中将对象类型属性的值分配给具有相同属性属性的不同对象类型?

如何将 mysql 数字类型数据从 php 传递到 Javascript 以作为字符串类型到达? [关闭]

如何将 deviceToken 字符串传递给“webViewDidFinishLoad”?

在 Kotlin Android 中将值传递给函数时进行编译时间检查

如何在 Python 中将日期传递给 MySQLdb?

如何在 PLSQL 过程中将绑定变量作为 IN OUT 参数传递