有人可以向我解释以下两个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(,),但我并不想在应用程序中使用硬编码长度,因为这些可能会在将来发生变化。
有没有人对此有任何想法?提前感谢您的帮助!
答案 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数据库进行隐式数据类型转换的方向:
您可以浏览here
的完整数据类型比较规则列表