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

C# 根据C中第一次插入的序列号插入到3个表中#,c#,asp.net,sql,oracle,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)

我在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#中执行上述所有操作或不执行任何操作


如果第一次第二次或第三次插入失败,则所有操作都应失败

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

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

commit transaction

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

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

可供替代的
insert语句可以移动到存储过程中(最好是在包中),因此只能从C#进行一次查询。

这只是另一个想法-您可以使用一个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
生成的序列是什么。如果您想保留每个表的单独插入,您可以通过引用
contactID来获取最近生成的值。CurrVal

与您的问题无关,但您应该在SQL查询中使用
Bind variables
/
parameters
。。。
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)