2009-11-09 77 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) 

這也將這樣做。