Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ODP.NET中是否有机制将发送查询推迟到提交?_C#_.net_Oracle_Odp.net_Transactionscope - Fatal编程技术网

C# ODP.NET中是否有机制将发送查询推迟到提交?

C# ODP.NET中是否有机制将发送查询推迟到提交?,c#,.net,oracle,odp.net,transactionscope,C#,.net,Oracle,Odp.net,Transactionscope,假设我有一个包含1000个查询的列表,其中包括INSERT、UPDATE和DELETE操作。我想在事务中运行它们 此外,我不想将每个查询单独发送到数据库,因为往返时间是1000倍 是否有任何机制告诉ODP.NET将查询保留在内存中,然后在提交时使用一个聚合查询发送整个查询(因此需要1个往返时间) 一个简单的(愚蠢的!?)解决方案是实用地在局部变量中创建一个大型文本查询,然后将其传递给命令并执行它 很明显,通过这种方式,在发送查询之前不会有锁,这在我的情况下并不重要。您可以使用关联数组参数创建一个

假设我有一个包含1000个查询的列表,其中包括
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,那么我回到我的第一条评论:尽量在服务器端而不是客户端生成语句。