使用 oracle 参数绑定变量
bound variables using oracle parameters
寻找在 execute immediate
语句中绑定 oracle 参数的可能性。但现在面临的问题是,由于 Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-01008: not all variables bound exception
,我无法在一个语句中执行多个查询。经过研究,我不知道是否可以这样做。
var cmd = new OracleCommand
{
CommandText = "begin " +
$" execute immediate 'CREATE PRIVATE TEMPORARY TABLE ORA$PTT_USERSTMP AS SELECT {string.Join(',', columnNames)} from USERS WHERE 1=0';" +
$" execute immediate 'INSERT INTO ORA$PTT_USERSTMP ({string.Join(',', columnNames)}) VALUES ({string.Join(',', columnNames.Select((c, index) => $":{index + 1}"))})';" +
"end;"
};
cmd.ArrayBindCount = valuesToInsert.First().Count();
foreach (var value in valuesToInsert)
{
cmd.Parameters.Add(new OracleParameter { OracleDbType = GetType(value), Value = value });
}
await cmd.ExecuteNonQueryAsync();
有什么办法可以做到这一点,或者我应该实施使用多个命令语句并在没有 'execute immediate'
的情况下始终如一地执行它们
更新 1
添加了 using
语句并且它有效但现在遇到另一个问题,我在 oracle 命令中添加了一个语句以从临时更新 table,但面临另一个问题:Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-32462: cannot use an object modified in current transaction
,使用以下命令更新语句:
var cmd = new OracleCommand
{
CommandText = "begin " +
$" execute immediate 'CREATE PRIVATE TEMPORARY TABLE ORA$PTT_USERSTMP AS SELECT {string.Join(',', columnNames)} from USERS WHERE 1=0';" +
$" execute immediate 'INSERT INTO ORA$PTT_USERSTMP ({string.Join(',', columnNames)}) VALUES ({string.Join(',', columnNames.Select((c, index) => $":{index + 1}"))})' using {string.Join(',', columnNames.Select((c, index) => $":{index + 1}"))};" +
$" execute immediate 'UPDATE USERS2 t1 SET ({string.Join(',', columnNames.Where(s => s != idColumnName).Select(s => "t1." + s))}) = (SELECT {string.Join(',', columnNames.Where(s => s != idColumnName).Select(s => "t2." + s))} FROM ORA$PTT_USERSTMP t2 WHERE t1.{idColumnName} = t2.{idColumnName})';" +
" execute immediate 'DROP TABLE ORA$PTT_USERSTMP';" +
"end;"
};
[此处][1] 描述的错误 ORA-32462 简单意味着 table USERS
包含 未提交的更改 并且您不能使用用 CTAS
创建一个 PRIVATE TEMPORARY TABLE
create PRIVATE TEMPORARY TABLE ORA$PTT_USERSTMP as select * from USERS where 1=0;
触发器
ORA-32462: cannot use an object modified in current transaction
因此,如果PTT
,您必须commit
创建之前的事务,或者如果不可行,则将创建拆分为create table
和insert
简化示例
begin
execute immediate 'create PRIVATE TEMPORARY TABLE ORA$PTT_USERSTMP (id int, col int)';
execute immediate 'insert into ORA$PTT_USERSTMP(id,col) values(:1,:2)' using 1, 999;
...
顺便说一下,您可以用 ON COMMIT DROP DEFINITION
定义 PTT
,这可以消除 excplicite DROP
的需要
[1]: ORA-32462: cannot use an object modified in current transaction
寻找在 execute immediate
语句中绑定 oracle 参数的可能性。但现在面临的问题是,由于 Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-01008: not all variables bound exception
,我无法在一个语句中执行多个查询。经过研究,我不知道是否可以这样做。
var cmd = new OracleCommand
{
CommandText = "begin " +
$" execute immediate 'CREATE PRIVATE TEMPORARY TABLE ORA$PTT_USERSTMP AS SELECT {string.Join(',', columnNames)} from USERS WHERE 1=0';" +
$" execute immediate 'INSERT INTO ORA$PTT_USERSTMP ({string.Join(',', columnNames)}) VALUES ({string.Join(',', columnNames.Select((c, index) => $":{index + 1}"))})';" +
"end;"
};
cmd.ArrayBindCount = valuesToInsert.First().Count();
foreach (var value in valuesToInsert)
{
cmd.Parameters.Add(new OracleParameter { OracleDbType = GetType(value), Value = value });
}
await cmd.ExecuteNonQueryAsync();
有什么办法可以做到这一点,或者我应该实施使用多个命令语句并在没有 'execute immediate'
的情况下始终如一地执行它们更新 1
添加了 using
语句并且它有效但现在遇到另一个问题,我在 oracle 命令中添加了一个语句以从临时更新 table,但面临另一个问题:Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-32462: cannot use an object modified in current transaction
,使用以下命令更新语句:
var cmd = new OracleCommand
{
CommandText = "begin " +
$" execute immediate 'CREATE PRIVATE TEMPORARY TABLE ORA$PTT_USERSTMP AS SELECT {string.Join(',', columnNames)} from USERS WHERE 1=0';" +
$" execute immediate 'INSERT INTO ORA$PTT_USERSTMP ({string.Join(',', columnNames)}) VALUES ({string.Join(',', columnNames.Select((c, index) => $":{index + 1}"))})' using {string.Join(',', columnNames.Select((c, index) => $":{index + 1}"))};" +
$" execute immediate 'UPDATE USERS2 t1 SET ({string.Join(',', columnNames.Where(s => s != idColumnName).Select(s => "t1." + s))}) = (SELECT {string.Join(',', columnNames.Where(s => s != idColumnName).Select(s => "t2." + s))} FROM ORA$PTT_USERSTMP t2 WHERE t1.{idColumnName} = t2.{idColumnName})';" +
" execute immediate 'DROP TABLE ORA$PTT_USERSTMP';" +
"end;"
};
[此处][1] 描述的错误 ORA-32462 简单意味着 table USERS
包含 未提交的更改 并且您不能使用用 CTAS
PRIVATE TEMPORARY TABLE
create PRIVATE TEMPORARY TABLE ORA$PTT_USERSTMP as select * from USERS where 1=0;
触发器
ORA-32462: cannot use an object modified in current transaction
因此,如果PTT
,您必须commit
创建之前的事务,或者如果不可行,则将创建拆分为create table
和insert
简化示例
begin
execute immediate 'create PRIVATE TEMPORARY TABLE ORA$PTT_USERSTMP (id int, col int)';
execute immediate 'insert into ORA$PTT_USERSTMP(id,col) values(:1,:2)' using 1, 999;
...
顺便说一下,您可以用 ON COMMIT DROP DEFINITION
定义 PTT
,这可以消除 excplicite DROP
的需要
[1]: ORA-32462: cannot use an object modified in current transaction