根据 C# 中第一次插入的序列号插入 3 个表

发布于 2024-10-17 23:45:57 字数 585 浏览 4 评论 0原文

我在 Oracle 数据库中有 3 个表。在我的 asp.net C# 页面中,我将记录插入到所有三个表中,如下所示:

INSERT INTO contactMaster
   (contactID, FName, MName, LName) 
VALUES
   (contactID.NextVal, 'John', 'G', 'Garnet')

INSERT INTO contactPhone
  (contactPhoneID, contactID, contactType, phonenum)     
VALUES
  (contactPhoneID.NextVal, 1, 2, 1234567890)

INSERT INTO contactAddress
  (contactAddressID, contactID, addressType, PHN, Street, City)
VALUES
  (contactAddressID.NextVal, 1, 1, 287, 'Blooper St', 'New Yor')

我的问题是,如何确保在 C# 中执行上述所有内容或不执行任何内容。

如果第一个第二个或第三个插入失败,则一切都应该失败。

I have 3 tables in Oracle database. From my asp.net C# page, I am inserting records into all three tables as shown below:

INSERT INTO contactMaster
   (contactID, FName, MName, LName) 
VALUES
   (contactID.NextVal, 'John', 'G', 'Garnet')

INSERT INTO contactPhone
  (contactPhoneID, contactID, contactType, phonenum)     
VALUES
  (contactPhoneID.NextVal, 1, 2, 1234567890)

INSERT INTO contactAddress
  (contactAddressID, contactID, addressType, PHN, Street, City)
VALUES
  (contactAddressID.NextVal, 1, 1, 287, 'Blooper St', 'New Yor')

My question is, how do I make sure that either all the above are executed or none is executed in C#.

If the first 2nd or 3rd insert fails, everything should fail.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尐籹人 2024-10-24 23:45:57

使用 SQL 事务来确保原子性:

public void RunOracleTransaction(string connectionString) {
  using (OracleConnection connection = new OracleConnection(connectionString))
  {
    connection.Open();

    OracleCommand command = connection.CreateCommand();
    OracleTransaction transaction;

    // Start a local transaction
    transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
    // Assign transaction object for a pending local transaction
    command.Transaction = transaction;

    try
    {
        command.CommandText = 
            "INSERT INTO contactMaster
               (contactID, FName, MName, LName) 
             VALUES
               (contactID.NextVal, 'John', 'G', 'Garnet')";
        command.ExecuteNonQuery();

        command.CommandText = 
            "INSERT INTO contactPhone
               (contactPhoneID, contactID, contactType, phonenum)     
             VALUES
               (contactPhoneID.NextVal, 1, 2, 1234567890)";
        command.ExecuteNonQuery();

        command.CommandText = 
            "INSERT INTO contactAddress
               (contactAddressID, contactID, addressType, PHN, Street, City)
             VALUES
               (contactAddressID.NextVal, 1, 1, 287, 'Blooper St', 'New Yor')";
        command.ExecuteNonQuery();

        transaction.Commit();
        Console.WriteLine("Both records are written to database.");
    }
    catch (Exception e)
    {
        transaction.Rollback();
        Console.WriteLine(e.ToString());
        Console.WriteLine("Neither record was written to database.");
    }
  }
}

C#: OracleTransaction

替代方案

插入语句可以移至存储过程(最好在包内),因此只需从 C# 进行单个查询。

Use a SQL transaction to ensure atomicity:

public void RunOracleTransaction(string connectionString) {
  using (OracleConnection connection = new OracleConnection(connectionString))
  {
    connection.Open();

    OracleCommand command = connection.CreateCommand();
    OracleTransaction transaction;

    // Start a local transaction
    transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
    // Assign transaction object for a pending local transaction
    command.Transaction = transaction;

    try
    {
        command.CommandText = 
            "INSERT INTO contactMaster
               (contactID, FName, MName, LName) 
             VALUES
               (contactID.NextVal, 'John', 'G', 'Garnet')";
        command.ExecuteNonQuery();

        command.CommandText = 
            "INSERT INTO contactPhone
               (contactPhoneID, contactID, contactType, phonenum)     
             VALUES
               (contactPhoneID.NextVal, 1, 2, 1234567890)";
        command.ExecuteNonQuery();

        command.CommandText = 
            "INSERT INTO contactAddress
               (contactAddressID, contactID, addressType, PHN, Street, City)
             VALUES
               (contactAddressID.NextVal, 1, 1, 287, 'Blooper St', 'New Yor')";
        command.ExecuteNonQuery();

        transaction.Commit();
        Console.WriteLine("Both records are written to database.");
    }
    catch (Exception e)
    {
        transaction.Rollback();
        Console.WriteLine(e.ToString());
        Console.WriteLine("Neither record was written to database.");
    }
  }
}

C#: OracleTransaction

Alternative

The insert statements could be moved to a stored procedure (preferably within a package), so only a single query be made from C#.

別甾虛僞 2024-10-24 23:45:57

只是另一个想法 - 您可以使用一个 INSERT 语句进行插入,例如:

INSERT ALL
INTO contactMaster
   (contactID, FName, MName, LName) 
VALUES
   (contactID, FName, MName, LName)
INTO contactPhone
  (contactPhoneID, contactID, contactType, phonenum)     
VALUES
  (contactPhoneID.NextVal, contactID, contactType, phonenum)
INTO contactAddress
  (contactAddressID, contactID, addressType, PHN, Street, City)
VALUES
  (contactAddressID.NextVal, contactID, addressType, PHN, Street, City)
(SELECT contactID.NextVal AS contactID,
        'John' AS FName,
        'G' AS MName,
        'Garnet' AS LName,
        2 AS contactType,
        1234567890 AS phonenum,
        1 AS addressType,
        287 AS PHN,
        'Blooper St' AS Street,
        'New Yor' AS City
 FROM   dual)

顺便说一下,您的原始插入似乎遇到 contactID 始终 1 的问题,无论为 contactMaster.contactID 生成的序列是什么。如果您想为每个表保留单独的 INSERT,您可以通过引用 contactID.CurrVal 获取最近生成的值。

Just another idea - you can do the inserts using one INSERT statement, e.g.:

INSERT ALL
INTO contactMaster
   (contactID, FName, MName, LName) 
VALUES
   (contactID, FName, MName, LName)
INTO contactPhone
  (contactPhoneID, contactID, contactType, phonenum)     
VALUES
  (contactPhoneID.NextVal, contactID, contactType, phonenum)
INTO contactAddress
  (contactAddressID, contactID, addressType, PHN, Street, City)
VALUES
  (contactAddressID.NextVal, contactID, addressType, PHN, Street, City)
(SELECT contactID.NextVal AS contactID,
        'John' AS FName,
        'G' AS MName,
        'Garnet' AS LName,
        2 AS contactType,
        1234567890 AS phonenum,
        1 AS addressType,
        287 AS PHN,
        'Blooper St' AS Street,
        'New Yor' AS City
 FROM   dual)

By the way, it looks like your original inserts suffer from the problem that contactID is always 1, regardless of what the sequence generated for contactMaster.contactID. If you want to stay with separate INSERTs for each table, you can get the most recently generated value by referring to contactID.CurrVal.

倾`听者〃 2024-10-24 23:45:57

在第一个命令之前,启动一个事务

start transaction

在最后一个命令之后,提交事务:

commit transaction

您可以一次性将这些事务发送到数据库,也可以使用单独的命令。无论哪种方式,所有插入都会被保留,或者不会被保留。

Before the first command, start a transaction:

start transaction

After the last command, commit the transaction:

commit transaction

You can send these to the database in one go, or using separate commands. Either way, either all or none of the inserts will be persisted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文