在varix中将一些字符串保存到整数字段的cast varchar

时间:2016-03-23 14:28:32

标签: sql casting informix

我想要比较数据库中的2个表中的2行。

Column1位于table1上,是一个Integer字段,其条目如下所示

column1 147518 187146 169592

Column2在table2上,是一个包含各种条目的Varchar(15)字段,但是对于这个例子,我们可以使用这3个:

column2 169592 00010000089 DummyId

对于我的查询,它的一部分依赖于检查table1中的行是否链接到table2中的行,但为了做到这一点,我需要比较column1和column2。

SELECT * FROM table1 WHERE column1 IN (SELECT column2 FROM table2)

使用上述数据的结果应为1行 - 169592

显然这不会起作用(数字转换过程中的字符失败),因为它们无法按原样进行比较,但我如何让它们起作用?

我试过了

SELECT * FROM table1 WHERE column1 IN (SELECT CAST(column2 AS INTEGER) FROM table2)

SELECT * FROM table1 WHERE column1 IN (SELECT (column2::INTEGER) column2 FROM table2)

如果有帮助,请使用Server Studio 9.1。

4 个答案:

答案 0 :(得分:1)

您可以尝试在以下内容中使用ISNUMERIC

SELECT * FROM table1 WHERE column1 IN (SELECT CASE WHEN ISNUMERIC(column2) = 1 THEN CAST(column2 AS INT) END FROM table2)

答案 1 :(得分:1)

尝试将int转换为字符串:

SELECT * FROM table1 WHERE cast(column1 as varchar(15)) IN (SELECT column2 FROM table2)

答案 2 :(得分:1)

为此目的,无需创建在其他环境中找不到的特殊功能。

让我们为您的示例创建一个测试用例:

CREATE TABLE tab1 (
        col1 INT,
        col2 INT
);

CREATE TABLE tab2 (
        col1 VARCHAR(15)
);

INSERT INTO tab1 VALUES(147518,1);
INSERT INTO tab1 VALUES(187146,2);
INSERT INTO tab1 VALUES(169592,3);

INSERT INTO tab2 VALUES(169592);
INSERT INTO tab2 VALUES('00010000089');
INSERT INTO tab2 VALUES('DummyId');

您运行的第一个查询是:

SELECT  t1.*
FROM    tab1 AS t1
WHERE   t1.col1 IN (SELECT t2.col1 FROM tab2 AS t2);

这会引发错误,因为它会尝试将INTVARCHAR进行比较

  

[infx1210 @ tardis~] $ finderr 1213     -1213字符到数字转换过程失败。

     

正在将字符值转换为数字形式以便存储在a中     数字列或变量。但是,字符串不能     解释为数字。它包含除白色之外的一些字符     空格,数字,符号,小数或字母e;或部分在     错误的顺序,所以数字不能破译。

     

如果您使用NLS,十进制字符或千位分隔符     你的语言环境可能有问题。

     

[infx1210 @ tardis~] $

然后你试图将VARCHAR投射到INT导致同样的错误,你应该尝试另一种方式:

> SELECT  t1.*
> FROM    tab1 AS t1
> WHERE   t1.col1::CHAR(11) IN (SELECT t2.col1 FROM tab2 AS t2);
>

       col1        col2

     169592           3

1 row(s) retrieved.

>

使用EXISTS

检查您是否获得更快的结果
>   SELECT        t1.*
>   FROM    tab1 AS t1
>   WHERE   EXISTS (
>                       SELECT  1
>                       FROM    tab2 AS t2
>                       WHERE   t1.col1::CHAR(11) = t2.col1
>   );

       col1        col2

     169592           3

1 row(s) retrieved.

>

另一种方法是加入表:

> SELECT    t1.*
> FROM      tab1 AS t1
>               INNER JOIN tab2 AS t2
>                   ON (t1.col1 = t2.col1);

       col1        col2

     169592           3

1 row(s) retrieved.

>

答案 3 :(得分:0)

@StanislovasKalašnikovas回答了这个问题的一部分,他说要使用以下内容:

SELECT * FROM table1 WHERE column1 IN (SELECT CASE WHEN ISNUMERIC(column2) = 1 THEN CAST(column2 AS INT) END FROM table2)

但是informix没有ISNUMERIC的内置函数,所以下面创建了它:

create function isnumeric2(inputstr varchar(15)) returning integer;
define numeric_var decimal(15,0);
define function_rtn integer;

on exception in (-1213)
let function_rtn = 0;
end exception with resume

let function_rtn = 1;
let numeric_var = inputstr;

return function_rtn;
end function;

然后上面的第一个查询对我有用。