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

时间:2011-02-19 18:37:32

标签: c# asp.net sql oracle

我在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#中不执行任何操作。

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

3 个答案:

答案 0 :(得分:2)

使用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

替代

可以将insert语句移动到存储过程(最好是在包中),因此只能从C#中进行单个查询。

答案 1 :(得分:1)

另一个想法 - 你可以使用一个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来获取最近生成的值。

答案 2 :(得分:0)

在第一个命令之前,启动transaction

start transaction

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

commit transaction

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