我认为我在Oracle数据库(10g)上的PL / SQL中遇到了一个相当简单的问题,我希望你们中的一个能帮助我。
我试图尽可能清楚地解释这一点,但这对我来说很难。 当我尝试比较2个不同表的varchar2值以检查是否需要创建新记录或者我可以重新使用现有ID时,DB(或I)以错误的方式比较这些值。当字段都包含值时,一切都很好,这导致它理解的'a'='a'。但是当两个字段都为NULL(或者'哪个Oracle将变为NULL)时,它无法比较字段。
我找到了解决这个问题的“解决方案”,但我确信有更好的方法。
rowTable1 ROWTABLE1%ROWTYPE;
iReUsableID INT;
SELECT * INTO rowTable1
FROM TABLE1
WHERE TABLE1ID = 'someID';
SELECT TABLE2ID INTO iReUsableID
FROM TABLE2
WHERE NVL(SOMEFIELDNAME,' ') = NVL(rowTable1.SOMEFIELDNAME,' ');
因此,NVL会将null
值更改为' '
,之后会以正确的方式进行比较。
提前致谢,
丹尼斯
答案 0 :(得分:2)
您可以使用LNNVL
函数(http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions078.htm)并撤消条件:
SELECT TABLE2ID INTO iReUsableID
FROM TABLE2
WHERE LNNVL(SOMEFIELDNAME != rowTable1.SOMEFIELDNAME);
答案 1 :(得分:0)
在Oracle(或我认为的任何RDBMS)中,一个NULL不等于另一个NULL。因此,如果要强制将2个NULL值视为相同,则需要使用已声明的变通方法。此外,您可能希望将NULL值默认为''(空)而不是''(空格)。
来自维基百科(最初是ISO规范,但我无法访问它):
由于Null不是任何数据域的成员,因此它不被视为“值”,而是指示缺少值的标记(或占位符)。因此,与Null的比较永远不会导致True或False,但总是在第三个逻辑结果中,Unknown。
如Jan Spurny所述,您可以使用LNNVL
进行比较。但是,当比较两个值都为NULL时,实际进行比较是错误的。
答案 2 :(得分:0)
这确实是一种比较空值的简单而有用的方法。 您无法直接比较NULLS,因为NULL不等于NULL。 您必须提供自己想要比较的逻辑,以及您对NVL()的所作所为。 请记住,您将NULLS视为空格,因此在您的情况下,在一个表中,''在另一个表中等于NULL。
我认为还有其他一些方法(例如LNNVL),但它们不是某种“更好”的方式。
答案 3 :(得分:0)
您的方法没问题,除非其中一个值可能是空格。进行比较的“标准”方式是明确地与NULL
:
WHERE col1 = col2 or col1 is null and col2 is null
在Oracle中,字符串的比较受到Oracle将空字符串视为NULL的事实的阻碍。这是Oracle的特性,而不是其他数据库中的问题。