考虑我有一个包含INSERT
,UPDATE
和DELETE
操作的1000个查询的列表。我想在交易中运行它们。
此外,由于1000倍的往返时间,我不想单独将每个查询发送到数据库。
是否有任何机制告诉ODP.NET将查询保留在内存中,然后在提交时使用一个聚合查询发送整个查询(所以1次往返时间)
一个简单的(愚蠢的!?)解决方案是在本地变量中以实际方式创建一个大型文本查询,然后将其传递给命令并执行它。
很明显,这样在发送查询之前就没有锁定,这在我的情况下无关紧要。
答案 0 :(得分:0)
您可以使用关联数组参数创建过程。将所有DML放入此数组,将其发送到DB并在循环中执行它们。我在VB.NET中有一个例子:
Public Sub DynamicDML()
Dim cmd As OracleCommand
Dim par As OracleParameter
Dim DML As New List(Of String), dmlArray As String()
DML.Add("DELETE FROM TABLE_A")
DML.Add"INSERT INTO TABLE_B VALUES (...)")
DML.Add("UPDATE TABLE_C SET ...")
dmlArray = DML.ToArray
cmd = New OracleCommand("BEGIN MyProcedure(:lines); END;", server.con)
cmd.CommandType = CommandType.Text
par = cmd.Parameters.Add("lines", OracleDbType.Varchar2, ParameterDirection.Input)
par.CollectionType = OracleCollectionType.PLSQLAssociativeArray
par.Value = dmlArray
par.Size = dmlArray.Length
cmd.ExecuteNonQuery()
End Sub
在Oracle方面:
CREATE OR REPLACE PACKAGE DML_PACKAGE AS
TYPE TArrayOfVarchar2 IS TABLE OF VARCHAR2(1000) INDEX BY BINARY_INTEGER;
PROCEDURE MyProcedure(lines IN TArrayOfVarchar2);
END DML_PACKAGE;
/
CREATE OR REPLACE PACKAGE BODY DML_PACKAGE AS
PROCEDURE MyProcedure(lines IN TArrayOfVarchar2) IS
BEGIN
FOR i IN lines.FIRST..lines.LAST LOOP
EXECUTE IMMEDIATE lines(i);
END LOOP;
END MyProcedure;
END DML_PACKAGE;
/
无论如何,我认为最终用户的单个动作可以触发1000个不同的 DML语句,这些语句必须逐个单独生成。我很确定大部分都可以通过触发器,约束,程序,批量操作等来完成。