这段代码不起作用:
using (var conn = new OracleConnection(ConnString))
{
conn.Open();
using (var t = conn.BeginTransaction())
{
var sanitizer = new HtmlSanitizer();
var sqlWithSubquery = @"INSERT INTO owner.dummy_table (idDog, idCat, idBunny) VALUES (
SequenceDogs.nextval,
:Parameter_IdCat,
(SELECT idBunny FROM owner.bunny_table WHERE
IdTree = :Parameter_IdTree))";
var cmdInsertWithSubquery = new OracleCommand(sqlWithSubquery.ToString(), conn);
cmdInsertWithSubquery.Parameters.Add(new OracleParameter("Parameter_IdCat", OracleDbType.Int32)).Value = sanitizer.Sanitize(idCat);
cmdInsertWithSubquery.Parameters.Add(new OracleParameter("Parameter_IdTree", OracleDbType.Int32)).Value = sanitizer.Sanitize(idTree);
cmdInsertWithSubquery.CommandType = System.Data.CommandType.Text;
var result = cmdInsertWithSubquery.ExecuteNonQueryAsync();
if (result.Status == TaskStatus.Faulted)
{
sbLog.AppendLine(result.Exception.InnerException.Message.ToString());
}
else
{
sbLog.AppendLine("Success");
}
t.Commit();
conn.Close();
}
}
它会导致错误:ORA-01400:无法将NULL插入(“owner”.“dummy_table”.“idBunny”)
而下面的工作刚刚好:
using (var conn = new OracleConnection(ConnString))
{
conn.Open();
using (var t = conn.BeginTransaction())
{
var sanitizer = new HtmlSanitizer();
// Doing the subquery apart, because for some reason it won't work inside an INSERT
var sqlSubquery = @"SELECT idBunny FROM owner.bunny_table WHERE
IdTree = :Parameter_IdTree";
var cmdSubquery = new OracleCommand(sqlSubquery.ToString(), conn);
cmdSubquery.Parameters.Add(new OracleParameter("Parameter_IdTree", OracleDbType.Int32)).Value = sanitizer.Sanitize(idTree);
cmdSubquery.CommandType = System.Data.CommandType.Text;
var idBunny = cmdSubquery.ExecuteScalar();
var sqlInsert = @"INSERT INTO owner.dummy_table (idDog, idCat, idBunny) VALUES (
SequenceDogs.nextval,
:Parameter_IdCat,
:Parameter_IdBunny)";
var cmdInsert = new OracleCommand(sqlInsert.ToString(), conn);
cmdInsert.Parameters.Add(new OracleParameter("Parameter_IdCat", OracleDbType.Int32)).Value = sanitizer.Sanitize(idCat);
cmdInsert.Parameters.Add(new OracleParameter("Parameter_IdBunny", OracleDbType.Int32)).Value = sanitizer.Sanitize(idBunny.ToString());
cmdInsert.CommandType = System.Data.CommandType.Text;
var result = cmdInsert.ExecuteNonQueryAsync();
if (result.Status == TaskStatus.Faulted)
{
sbLog.AppendLine(result.Exception.InnerException.Message.ToString());
}
else
{
sbLog.AppendLine("Success");
}
t.Commit();
conn.Close();
}
}
问题解决了,但它看起来像一个丑陋的解决方案,我想知道为什么第一种方法是无效的。
是绑定过程中的一些bug还是设计的一个特性?
1条答案
按热度按时间kgqe7b3p1#
就我从这篇文章(Oracle identity column and insert into select)中所能收集到的信息而言,一个变通方案可能是
它还没有经过测试,但可能会让你找到解决方案。正如已经指出的,确保idBunny不会导致NULL值(在WHERE子句中添加 idBunny IS NOT NULL 以确保安全)。