C# ODP.NET中是否有机制将发送查询推迟到提交?
假设我有一个包含1000个查询的列表,其中包括C# ODP.NET中是否有机制将发送查询推迟到提交?,c#,.net,oracle,odp.net,transactionscope,C#,.net,Oracle,Odp.net,Transactionscope,假设我有一个包含1000个查询的列表,其中包括INSERT、UPDATE和DELETE操作。我想在事务中运行它们 此外,我不想将每个查询单独发送到数据库,因为往返时间是1000倍 是否有任何机制告诉ODP.NET将查询保留在内存中,然后在提交时使用一个聚合查询发送整个查询(因此需要1个往返时间) 一个简单的(愚蠢的!?)解决方案是实用地在局部变量中创建一个大型文本查询,然后将其传递给命令并执行它 很明显,通过这种方式,在发送查询之前不会有锁,这在我的情况下并不重要。您可以使用关联数组参数创建一个
INSERT
、UPDATE
和DELETE
操作。我想在事务中运行它们
此外,我不想将每个查询单独发送到数据库,因为往返时间是1000倍
是否有任何机制告诉ODP.NET将查询保留在内存中,然后在提交时使用一个聚合查询发送整个查询(因此需要1个往返时间)
一个简单的(愚蠢的!?)解决方案是实用地在局部变量中创建一个大型文本查询,然后将其传递给命令并执行它
很明显,通过这种方式,在发送查询之前不会有锁,这在我的情况下并不重要。您可以使用关联数组参数创建一个过程。将所有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语句,这些语句必须逐个生成。我敢肯定,它们中的大多数都可以通过触发器、约束、过程、批量操作等来完成。使用存储过程。创建一个DML,无论是作为包的一部分(首选)还是作为独立的,放置所有DML,它应该是事务的一部分,并调用该存储过程。@NicholasKrasnov问题是查询是动态生成的。这不是一个固定的查询。那么,我想问更多的信息和一个例子。谁、何时以及如何生成这些DML。我认为,即使是动态生成的,也可以简单地将这些DML括在
begin-end
块中。@NicholasKrasnov查询是由ORM(对象关系映射器)创建的。调用object.Persist()
时,ORM将遍历对象图,并根据每个对象节点的状态创建适当的查询。每种类型都有不同的图形,每个实例的图形节点都有不同的状态。@NicholasKrasnov事实上我已经使用了begin-end
块。我已经在中描述过了:但是它看起来很愚蠢,而且它不稳定。例如,在链接中,我对ODP.neta的奇怪行为有问题,事实上我使用的是相同的方法。但我想使用参数而不是原始查询发送参数。(为了避免SQL注入)@mehrandvd,那么我回到我的第一条评论:尽量在服务器端而不是客户端生成语句。