Oracle CHAR比较不起作用

时间:2015-02-09 22:15:34

标签: oracle

有人可以向我解释以下两个Oracle查询之间的区别吗?我知道它们看起来非常相似,但第一个返回结果而第二个不返回结果。我的功能实现也可以在下面看到。

--Returns results
SELECT *
FROM <TABLE_NAME>
WHERE ID = CAST(<UserID> AS CHAR(2000)); --ID is defined as CHAR(8) in the DB.

--Does not return results
SELECT *
FROM <TABLE_NAME>
WHERE ID = CAST_TO_CHAR(<UserID>); --ID is defined as CHAR(8) in the DB.

--Function definition
CREATE OR REPLACE FUNCTION CAST_TO_CHAR(varToPad IN VARCHAR2)
RETURN CHAR IS returnVal CHAR(2000);
BEGIN
SELECT CAST(varToPad AS CHAR(2000))
INTO returnVal
FROM DUAL;
RETURN returnVal;
END;
/

在我看来,从数据库中检索值时,类型不会持久存在。根据我从Oracle中的CHAR比较中理解,它将占用两个字段中较小的一个并截断较大的字段以使大小匹配(这就是我将第二个变量转换为长度2000的原因)。

我需要实现这样的原因是因为我们从DB2升级到Oracle的供应商工具将Oracle数据库中的所有列定义为CHAR而不是VARCHAR2。他们这样做是为了使他们的遗留代码更容易移植到分布式环境中。这在我们的Web应用程序中引起了很大的问题,因为现在正在针对固定长度的CHAR字段进行比较。

我考虑过使用TRIM(),但是这些查询会被大量访问,我不希望它们每次都进行全表扫描。我也考虑过RPAD(,),但我并不想在应用程序中使用硬编码长度,因为这些可能会在将来发生变化。

有没有人对此有任何想法?提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我有类似的问题。事实证明,这些是隐式数据转换的规则。当这种转换有意义时,Oracle数据库会自动将值从一种数据类型转换为另一种数据类型。

如果您更改了选择:

SELECT *
FROM <TABLE_NAME>
WHERE CAST(ID as CHAR(2000)) = CAST_TO_CHAR(<UserID>);

你会看到它正常运作。

这是另一个测试脚本,显示该功能正常工作:

SET SERVEROUTPUT ON --for DBMS_OUTPUT.PUT_LINE.
DECLARE
    test_string_c CHAR(8);    
    test_string_v VARCHAR2(8);
BEGIN
    --Assign the same value to each string.
    test_string_c := 'string';
    test_string_v := 'string';
    --Test the strings for equality.
    IF test_string_c = CAST_TO_CHAR(test_string_v) THEN
        DBMS_OUTPUT.PUT_LINE('The names are the same');
    ELSE
        DBMS_OUTPUT.PUT_LINE('The names are NOT the same');
    END IF;
END;
/

anonymous block completed
The names are the same

以下是一些规则管理Oracle数据库进行隐式数据类型转换的方向:

  • 在INSERT和UPDATE操作期间,Oracle将值转换为 受影响列的数据类型。
  • 在SELECT FROM操作期间,Oracle会转换数据 列到目标变量的类型。
  • 将字符值与数值进行比较时,Oracle 将字符数据转换为数字值。
  • 将字符值与DATE值进行比较时,Oracle会进行转换 字符数据到DATE。
  • 在进行分配时,Oracle会转换右侧的值 等号(=)到赋值目标的数据类型 在左侧。
  • 当您使用带参数为a的 SQL函数或运算符时 数据类型不是它接受的数据类型, Oracle转换参数 到接受的数据类型

您可以浏览here

的完整数据类型比较规则列表