【问题标题】:bound variables using oracle parameters使用 oracle 参数绑定变量
【发布时间】:2021-12-01 07:44:53
【问题描述】:

寻找在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();

有什么方法可以做到这一点,或者我应该实现使用多个命令语句并在没有“立即执行”的情况下一致地执行它们

更新 1 添加了using 语句并且它工作但现在遇到了另一个问题,我在 oracle 命令中添加了一个语句来从临时更新表,但面临另一个问题: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;"
};

【问题讨论】:

  • 检查USING clauseEXECUTE IMMEDIATE
  • @MarmiteBomber 是的,但是如何将它与我的解决方案结合起来?

标签: c# .net oracle ado.net


【解决方案1】:

[这里][1] 描述的错误 ORA-32462 简单意味着表 USERS 包含未提交的更改,您不能使用它通过 CTAS 创建 PRIVATE TEMPORARY TABLE p>

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 tableinsert

简化示例

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

【讨论】:

    猜你喜欢
    • 2019-07-23
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多