在C#中向Oracle发送大量数据。

huangapple go评论81阅读模式
英文:

Send large amount of data in Oracle in C#

问题

[BEGINNER]
抱歉我的英语不好。
我在新公司工作不久,我认为自己在BDD方面是个新手,除了学校以外,我很少练习。

[ENVIRONMENT]
我正在使用C#开发一个现有的软件,需要对其进行优化。但有一个重要的限制,不能修改数据库结构,因为许多客户已经在使用,并且不愿意更改他们的服务器。通常,如果他们使用ORACLE,那是因为他们也在用它来运行其他软件。

该软件使用System.Data.OracleClient,但后者已经过时,我开始使用Oracle.ManagedDataAccess.Client。我可以与数据库通信、读写数据,但无法快速发送大量数据。

我们现场有一个服务器,上面有一个远程数据库,使用的是Oracle或MySQL(目前我主要关注的是Oracle)。
还有本地工作站,使用SQLite数据库,必须能够在没有远程数据库的情况下运行。

默认情况下,所有数据都保存在本地,如果可以访问远程数据库,就需要进行同步。因此,可能需要传输大量数据(包括测量记录)。

[FOR MY TESTS]
我从客户数据库中恢复了一个,以便使用真实数据进行测试,其中一个表格有超过65万行。逐行传输需要很长时间,即使我当然不会在每一行都断开连接。
我想尝试发送参数块,但目前无法做到。

[MY RESEARCH]
我一直在寻找,但我找到的要么使用付费的DLL,要么我没有理解它们的用途。

[MY CODE]
目前我在测试中使用以下代码:

OracleConnection Connection = null;
public void testOracle()
{
    try
    {
        if (Connection == null)
        {
            Connection = OracleConnection();
        }
        string commandString = "INSERT INTO GRAPHE (ID, MESUREE_ID, DATE_MESURE, POINT_GRAPHE, D0, D1) VALUES (:IDp, :MESUREE_IDp, to_timestamp( :DATE_MESUREp ,'DD/MM/RR HH24:MI:SSXFF'), :POINT_GRAPHEp, :D0p, :D1p)";
        int _ID = 1;
        int _MESUREE_ID = 9624;
        string _DATE_MESURE = "16/12/ 08 00:00:00,000000000";
        int _POINT_GRAPHE = 1229421394;
        int[] _D0 = new int[0];
        int[] _D1 = new int[0];

        using (OracleCommand command = new OracleCommand(commandString, Connection))
        {

            using (var transaction = Connection.BeginTransaction())
            {
                for (int i = 0; i < _ID.Length; i++)
                {
                    command.Parameters.Add("IDp", OracleDbType.Decimal).Value = _ID;
                    command.Parameters.Add("MESUREE_IDp", OracleDbType.Decimal).Value = _MESUREE_ID;
                    command.Parameters.Add("DATE_MESUREp", OracleDbType.Varchar2).Value = _DATE_MESURE[i];
                    command.Parameters.Add("POINT_GRAPHEp", OracleDbType.Decimal).Value = _POINT_GRAPHE[i];
                    command.Parameters.Add("DOS10p", OracleDbType.Decimal).Value = _D0[i];
                    command.Parameters.Add("DOS07p", OracleDbType.Decimal).Value = _D1[i];
                    command.ExecuteNonQuery();
                }
                transaction.Commit();
            }
        }
    }
    catch (Exception ex)
    {

    }
    Connection.Close();
}

public OracleConnection OracleConnection()
{
    string serveur_name = "192.168.0.1";
    string database_name = "oracle.dev";
    string user_name = "name";
    string password = "pass";
    string oraclePort = "1521";
    OracleConnection _con = null;
    try
    {
        string connectionString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + serveur_name + ")(PORT=" + oraclePort + ")) (CONNECT_DATA=(SERVICE_NAME=" + database_name + "))); User Id=" + user_name + ";Password=" + password + ";";
        _con = new OracleConnection(connectionString);
        try
        {
            _con.Open();
        }
        catch (Exception e)
        {

        }
    }
    catch (Exception e)
    {

    }
    return _con;
}
}

请注意,我在代码中修复了一些错误,例如将int数组的初始化更正为new int[0]。如果有其他问题,或者需要进一步的帮助,请告诉我。

英文:

[BEGINNER]
Sorry for my English.
I've been working for a new company for a short time and I consider myself a novice in BDD, since apart from school I haven't practiced since.

[ENVIRONMENT]
I am developing in C# an existing software that I need to optimize. With a big constraint, it is not to modify the bases since many customers already use them and will not want to change their server. In general if he uses ORACLE it is because he also uses it for other software.

The software used System.Data.OracleClient, but the latter is obsolete, I started implementing Oracle.ManagedDataAccess.Client. I can communicate, read and write data with the database, but I can't send a large amount of data quickly.

On site we have a server with a remote base which is therefore with Oracle, or MySQL (what interests me for the moment is Oracle)
And there are local workstations that use an SQLite database and must be able to operate without the remote database.

By default everything is saved locally and I have synchronizations to do if the remote database is accessible. It is therefore possible to have a large amount of data to transfer. (there are measurement records)

[FOR MY TESTS]
I recovered one of the customer databases in order to do tests with real data and one of the tables with more than 650,000 rows.
Transferring this line by line takes a lot of time, even if I don't make disconnection connections on each line of course.
I wanted to try to send parameter blocks, but I can't do it at the moment.

[MY RESEARCH]
I keep looking, but what I found was either using paid DLLs or I didn't understand their use.

[MY CODE]
For the moment I left on it, really in test:

        public void testOracle()
{
try
{
if (Connection == null)
{
Connection = OracleConnection();
}
string commandString = &quot;INSERT INTO GRAPHE (ID, MESUREE_ID, DATE_MESURE, POINT_GRAPHE, D0, D1) VALUES (:IDp, :MESUREE_IDp, to_timestamp( :DATE_MESUREp ,&#39;DD/MM/RR HH24:MI:SSXFF&#39;), :POINT_GRAPHEp, :D0p, :D1p)&quot;;
int _ID = 1;
int _MESUREE_ID = 9624;
string _DATE_MESURE = &quot;16/12/ 08 00:00:00,000000000&quot;;
int _POINT_GRAPHE = 1229421394;
int[] _D0 = 0;
int[] _D1 = 0;
using (OracleCommand command = new OracleCommand(commandString, Connection))
{
using (var transaction = Connection.BeginTransaction())
{
for (int i = 0; i &lt; _ID.Length; i++)
{
command.Parameters.Add(&quot;IDp&quot;, OracleDbType.Decimal).Value = _ID;
command.Parameters.Add(&quot;MESUREE_IDp&quot;, OracleDbType.Decimal).Value = _MESUREE_ID];
command.Parameters.Add(&quot;DATE_MESUREp&quot;, OracleDbType.Varchar2).Value = _DATE_MESURE[i];
command.Parameters.Add(&quot;POINT_GRAPHEp&quot;, OracleDbType.Decimal).Value = _POINT_GRAPHE[i];
command.Parameters.Add(&quot;DOS10p&quot;, OracleDbType.Decimal).Value = _D0[i];
command.Parameters.Add(&quot;DOS07p&quot;, OracleDbType.Decimal).Value = _D1[i];
command.ExecuteNonQuery();
}
transaction.Commit();
}
}
}
catch (Exception ex)
{
}
Connection.Close();
}
public OracleConnection OracleConnection()
{
string serveur_name = &quot;192.168.0.1&quot;;
string database_name = &quot;oracle.dev&quot;;
string user_name = &quot;name&quot;;
string password = &quot;pass&quot;;
string oraclePort = &quot;1521&quot;;
OracleConnection _con = null;
try
{
string connectionString = &quot;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=&quot; + serveur_name + &quot;)(PORT=&quot; + oraclePort + &quot;)) (CONNECT_DATA=(SERVICE_NAME=&quot; + database_name + &quot;))); User Id=&quot; + user_name + &quot;;Password=&quot; + password + &quot;;&quot;;
_con = new OracleConnection(connectionString);
try
{
_con.Open();
}
catch (Exception e)
{
}
}
catch (Exception e)
{
}
return _con;
}
}```
</details>
# 答案1
**得分**: 1
然后您可以创建一个 DataTable 并执行批量插入
使用以下代码:
```csharp
using (var bulkCopy = new OracleBulkCopy(yourConnectionString, OracleBulkCopyOptions.UseInternalTransaction))
{
bulkCopy.DestinationTableName = "GRAPHE";
bulkCopy.WriteToServer(dataTable);
}

您还可以根据需要使用 BatchSize 属性。

英文:

then you can create a DataTable and do bulk insert

using (var bulkCopy = new OracleBulkCopy(yourConnectionString, OracleBulkCopyOptions.UseInternalTransaction))
{
bulkCopy.DestinationTableName = &quot;GRAPHE&quot;;
bulkCopy.WriteToServer(dataTable);
}

You can also use the BatchSize property as per your requirement.

huangapple
  • 本文由 发表于 2023年1月9日 17:51:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75055531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定