OracleParameter 和 DBNull.Value
Posted
技术标签:
【中文标题】OracleParameter 和 DBNull.Value【英文标题】:OracleParameter and DBNull.Value 【发布时间】:2009-11-09 14:37:41 【问题描述】:我们在 Oracle 数据库中有一个表,其中包含一个 Char(3 Byte) 类型的列。 现在我们使用参数化的 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的情况 也很明显。
有人可以解释这种行为吗?如何编写需要条件来检查 DBNull 的参数化 sql?
谢谢
【问题讨论】:
【参考方案1】:Null 是没有被设置为任何东西,因此您不会通过 '= null' 获得正确的行为。因为 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
除非您总是与 null 进行比较。然后,只需使用语句 2
【讨论】:
执行此操作时,请注意 Oracle 不会索引空值,可能会导致查询计划效率低下 我担心我不得不这样做,你刚刚证实了我的怀疑。这真的很笨拙。我希望有更好的方法...【参考方案2】:在这种情况下你必须使用IS NULL
:
string sql = "select * from TEST_TABLE where COLUMN_1 is null";
在 SQL 中与空值进行任何比较将始终产生unknown 结果,这意味着您不会得到任何返回的行。
【讨论】:
【参考方案3】:你可以这样做:
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 个具有相同值的参数。 ***.com/questions/1422032/…【参考方案4】:像这样修改你的代码:
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
【讨论】:
【参考方案5】: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)
这样也行。
【讨论】:
以上是关于OracleParameter 和 DBNull.Value的主要内容,如果未能解决你的问题,请参考以下文章
PL/SQL NVL 和 OracleParameter 在 C# 中不起作用
c# OracleParameter 抛出 ORA-06502