gpt4 book ai didi

.net - 在数组绑定(bind)中使用直接路径加载提示是否错误?

转载 作者:搜寻专家 更新时间:2023-10-30 19:45:19 26 4
gpt4 key购买 nike

作为迁移任务的一部分,我试图通过 .NET 应用程序(使用 ODP.NET)使用数组绑定(bind)将大量数据 (>30M) 插入到一个 1000/10000 行 block 的表中;有用。我认为如果我直接使用路径加载提示 /*+ APPEND_VALUES */ 会更快。但每当我尝试这样做时,我都会遇到异常:ORA-38910:BATCH ERROR MODE is not supported for this operation。在跟踪文件中(由 tkprof 收集,没有 sys)我发现了这些:

...

********************************************************************************

insert /*+ APPEND_VALUES */ into MYTABLE(COL1, COL2)
values (:COL1, :COL2)

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.00 0.00 0 0 0 0

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 122

Rows Row Source Operation
------- ---------------------------------------------------
0 LOAD AS SELECT (cr=0 pr=0 pw=0 time=0 us)
0 BULK BINDS GET (cr=0 pr=0 pw=0 time=0 us)


Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 3.14 3.20
SQL*Net break/reset to client 2 0.00 0.00
********************************************************************************

declare
m_stmt varchar2(512);
begin
m_stmt:='delete from sdo_geor_ddl__table$$';
EXECUTE IMMEDIATE m_stmt;
EXCEPTION
WHEN OTHERS THEN
NULL;
end;

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 0 0 1

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 57 (recursive depth: 1)
********************************************************************************

SQL ID: 3972rvxu3knn3
Plan Hash: 3007952250
delete from sdo_geor_ddl__table$$


call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 0 0 0

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 57 (recursive depth: 2)

Rows Row Source Operation
------- ---------------------------------------------------
0 DELETE SDO_GEOR_DDL__TABLE$$ (cr=0 pr=0 pw=0 time=0 us)
0 TABLE ACCESS FULL SDO_GEOR_DDL__TABLE$$ (cr=0 pr=0 pw=0 time=0 us cost=2 size=0 card=1)


... summary from here

我使用的代码:

private void TestArrayBindWithHint()
{
var data = new List<MyTableData>();

// ...
// data fetching + populating code here....
// ...

// Insert
using(var connection = GetConnection())
{
var insertQuery = "insert /*+ APPEND_VALUES */ into MYTABLE(COL1, COL2) values (:COL1, :COL2)";
using (var command = connection.CreateCommand())
{
command.CommandText = insertQuery;
command.CommandType = CommandType.Text;
command.BindByName = true;
command.ArrayBindCount = data.Count;

command.Parameters.Add(":COL1", OracleDbType.Int64, data.Select(d => d.COL1).ToArray(), ParameterDirection.Input);
command.Parameters.Add(":COL2", OracleDbType.Byte, data.Select(d => d.COL2).ToArray(), ParameterDirection.Input);
command.ExecuteNonQuery();
}
}
}

private ManagedDataAccess.Client.OracleConnection GetConnection()
{
const string identifier = "MYAPP";
var connection = new ManagedDataAccess.Client.OracleConnection(ConfigurationManager.AppSettings["connectionString"]);
connection.Open();
connection.ClientId = identifier;
ExecuteNonQuery(connection, string.Format(@"ALTER SESSION SET TRACEFILE_IDENTIFIER = ""{0}""", identifier));

return connection;
}

所以我的问题是:

  • 在数组绑定(bind)中使用直接路径加载提示是否错误?如果不是,我如何通过 ODP.NET 使用它?
  • 跟踪中的 delete from sdo_geor_ddl__table$$ DDL 是什么?为什么要生成它?

最佳答案

/*+ APPEND_VALUES */ 提示 Oracle 11.2 中引入的全新提示

通常,当您进行批量操作时,您会使用 FORALL ... SAVE EXCEPTIONS 语句,请参阅 FORALL .使用可选的 SAVE EXCEPTIONS 可以访问 SQL%BULK_EXCEPTIONS 属性,您可以在其中检索单个记录的异常。

当您使用 /*+ APPEND_VALUES */ 提示时,SQL%BULK_EXCEPTIONS 属性不可用,即您不能使用 SAVE EXCEPTIONS。就我个人而言,我认为这是 Oracle 中的一个错误,也许会在未来的版本中得到纠正。

显然 ODP.NET ExecuteNonQuery() 方法在内部始终以“批处理错误模式”运行,参见 Execution Modes of OCIStmtExecute() .这会导致错误。我看不到关闭“批处理错误模式”的任何可能性,因此您必须在没有 /*+ APPEND_VALUES */ 提示的情况下运行您的插入。

关于.net - 在数组绑定(bind)中使用直接路径加载提示是否错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40779201/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com