C# OracleParameter和DBNull.Value

C# OracleParameter和DBNull.Value,c#,sql,oracle,C#,Sql,Oracle,我们在Oracle数据库中有一个表,其中包含一个类型为Char(3字节)的列。 现在,我们使用参数化sql来选择一些具有DBNull.Value的行,但它不起作用: OracleCommand command = null; OracleDataReader dataReader = null; string sql = "select * from TEST_TABLE where COLUMN_1 = :COLUMN_1"; try { OracleConne

我们在Oracle数据库中有一个表,其中包含一个类型为Char(3字节)的列。
现在,我们使用参数化sql来选择一些具有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,
但是,在这种情况下,您将使用“is null”而不是“=null”编写一个“普通”sql
这也是显而易见的

有人能解释一下这种行为吗?如何编写一个参数化sql,其中需要一个条件来检查DBNull


感谢

Null是指没有设置为任何值,因此您无法使用“=Null”获得正确的行为。因为null表示没有值,所以说“这个缺少任何值的变量与另一个缺少任何值的变量具有相同的值”是没有意义的。如果没有值,则不能拥有其他变量的相同值

解决这个问题的一种方法是创建两个sql语句,一个接受参数,另一个使用“isnull”。然后使用“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

除非你总是比较空值。然后,just use statement 2

Null是指没有设置为任何值,因此无法获得“=Null”的正确行为。因为null表示没有值,所以说“这个缺少任何值的变量与另一个缺少任何值的变量具有相同的值”是没有意义的。如果没有值,则不能拥有其他变量的相同值

解决这个问题的一种方法是创建两个sql语句,一个接受参数,另一个使用“isnull”。然后使用“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

在这种情况下,您必须使用
为NULL

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

在SQL中执行任何与空值的比较都将产生一个结果,这意味着您将不会返回任何行。

在这种情况下,您必须使用
IS null

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

在SQL中使用空值执行任何比较都会产生一个结果,这意味着您将不会返回任何行。

修改代码如下:

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
}

按如下方式修改代码:

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
}
您可以这样做:

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)
您可以这样做:

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)
这也可以做到


这也可以做到。

使用“command.BindByName=true”避免将3个参数绑定为相同的值。使用“command.BindByName=true”避免将3个参数绑定为相同的值。当你这么做的时候,要注意Oracle不会索引空值,这可能会导致效率低下的查询计划。我担心我不得不这么做,你刚刚证实了我的怀疑。那真的很笨重。我希望有更好的方法……当你这样做时,要注意Oracle不会索引空值,这可能会导致查询计划效率低下。我担心我必须这样做,你刚刚证实了我的怀疑。那真的很笨重。我希望有更好的方法。。。