2009-11-09 105 views
1

我们在Oracle数据库中有一个表,其中包含一个Char类型为(3字节)的列。
现在我们使用参数化的SQL选择一些行用DBNull.Value和它不工作:OracleParameter和DBNull.Value

OracleCommand command = null; 
OracleDataReader dataReader = null; 

string sql = "select * from TEST_TABLE where COLUMN_1 = :COLUMN_1"; 

try 
{ 
    OracleConnection connection = (OracleConnection) dbConnection; 
    command = new OracleCommand(sql, connection); 

    OracleParameter param_1 = new OracleParameter("COLUMN_1", OracleDbType.Char); 
    command.Parameters.Add(param_1); 

    param_1.Value = DbNull.Value; 

    dataReader = command.ExecuteReader(); 

    int recordCount = 0; 
    while(dataReader.Read() == true) 
    { 
     recordCount++; 
    } 

    Console.WriteLine("Count = " + recordCount); // is 0 
} 
[...] 

我错过了什么?我们明确地有一些行包含一个DBNull,
但是你会写一个'正常'的SQL的情况是“空”而不是“=空”
也是显而易见的。

有人可以解释这种行为吗?你如何写一个参数化的SQL,你需要一个条件来检查DBNull?

感谢

回答

4

空是没有被设置为任何这样你就不会得到与“= NULL”正确的行为。因为空值是没有价值的,所以说“缺少任何值的这个变量与缺少任何值的其他变量具有相同的值是没有意义的”。如果你没有价值,你就无法获得与其他东西相同的价值。

解决此问题的一种方法是创建两个sql语句,一个接受参数,另一个接受'is null'。然后使用'if'语句来选择使用哪一个。

声明1:

string sql = "select * from TEST_TABLE where COLUMN_1 = :COLUMN_1 

声明2:

string sql = "select * from TEST_TABLE where COLUMN_1 is null 

也就是说,除非你总是比较空。然后,只需使用语句2

+1

当您这样做时,请注意Oracle不会索引空值,可能会导致查询计划效率低下 – erikkallen 2009-11-19 10:07:20

2

在这种情况下,你必须使用IS NULL

string sql = "select * from TEST_TABLE where COLUMN_1 is null"; 

进行任何比较,在SQL空值将总是导致unknown结果,这意味着你不会得到任何行返回。

1

修改你的代码是这样的:

OracleCommand command = null; 
OracleDataReader dataReader = null; 

string sql = "select * from TEST_TABLE where COLUMN_1 IS NULL" 

try 
{ 
    OracleConnection connection = (OracleConnection) dbConnection; 
    command = new OracleCommand(sql, connection); 

    dataReader = command.ExecuteReader(); 

    int recordCount = 0; 
    while(dataReader.Read() == true) 
    { 
     recordCount++; 
    } 

    Console.WriteLine("Count = " + recordCount); // is 0 
} 
2

,你可以这样做:

select * 
from TEST_TABLE 
where (COLUMN_1 = :COLUMN_1 and :COLUMN_1 Is Not Null) Or 
     (COLUMN_1 Is Null  and :COLUMN_1 Is Null) 
+0

使用'command.BindByName = true'可以避免使用相同的值绑定3个参数。 http://stackoverflow.com/questions/1422032/oracle-ora-01008-not-all-variables-bound-error-w-parameters/1425702#1425702 – Christian13467 2009-11-10 09:31:22

0
SELECT t1.* 
    FROM t1, (SELECT :s v FROM dual) tmp 
WHERE t1.s = tmp.v OR (t1.s IS NULL AND tmp.v IS NULL) 

这也将这样做。

相关问题