2014-01-13 2 views
0

내 SQL 서버 CE 데이터베이스에 다음과 같은 테이블이 있습니다응용 프로그램

ORDERS

OrderID (handled my DBMS) 
CustomerID 
OrderDate 

ORDER_DETAILS

OrderID (from the ORDERS table) 
ProductID 
OrderQTY 

I을 현재 2 개의 삽입 쿼리를 사용하여 새 주문을 데이터베이스에 추가합니다. 첫 번째는 ORDERS 테이블에 주문을 삽입하고 OrderID을 생성하는 DBMS와 ORDER_DETAILS 테이블에 삽입하기 위해 제공된 OrderID을 사용하는 두 번째 테이블입니다.

아래에서 사용한 접근법은 매우 복잡하고 잠재적으로 동시성 문제에 취약합니다. 새 레코드가 ORDERS 테이블에 삽입 될 때 ORDER_DETAILS 테이블에 대한 올바른 의 생성을 DBMS가 처리하도록 할 수 있습니까?

이것은 내가 삽입 쿼리를 실행하는 데 사용하는 C 번호는 다음과 같습니다

public int InsertOrder(Order order) 
    { 
     DBConnection connection = DBConnection.getInstance(); 
     connection.conn.Open(); 
     using (SqlCeCommand query = new SqlCeCommand(OrderCommandList.cmdInsertOrderHeader, connection.conn)) 
     { 
      query.Parameters.AddWithValue("@CustomerID", order.CustomerID); 
      query.Parameters.AddWithValue("@OrderDate", order.OrderDate); 
      query.ExecuteNonQuery(); 
     } 

     //retrieves the PK for the recently inserted record 
     int newOrderPK = 0; 
     using(SqlCeCommand cmdGetIdentity = new SqlCeCommand("SELECT @@IDENTITY", connection.conn)) 
     { 
      newOrderPK = Convert.ToInt32(cmdGetIdentity.ExecuteScalar()); 
     } 
     connection.conn.Close(); 
     InsertOrderDetails(order, newOrderPK); 
     return newOrderPK; 
    } 

    //inserts all the order details associated with the Order object 
    private void InsertOrderDetails(Order order, int orderForeignKey) 
    { 
     foreach (OrderDetail od in order.OrderLineItems) 
     { 
      DBConnection connection = DBConnection.getInstance(); 
      connection.conn.Open(); 
      using (SqlCeCommand query = new SqlCeCommand(OrderCommandList.cmdInsertOrderDetails, connection.conn)) 
      { 
       query.Parameters.AddWithValue("@OrderID", orderForeignKey); 
       query.Parameters.AddWithValue("@ProductID", od.ProductID); 
       query.Parameters.AddWithValue("@OrderQty", od.QtyOrdered); 
       query.ExecuteNonQuery(); 
      } 
      connection.conn.Close(); 
     } 
    } 
+0

이 질문에 C# 태그가 포함되어 있으므로 현재 데이터를 저장하기 위해 사용중인 C# 코드를 아는 것이 유용 할 수 있습니다. 계속 진행하는 것이 최선의 방법 일 수 있습니다. – jmcilhinney

답변

0
생성 된 ID 값을 선택하여 저장 프로 시저를 변경하고 SELECT SCOPE_IDENTITY();보다는 SELECT @@IDENTITY; 사용이

. 실제로 OUTPUT 매개 변수를 사용하는 것이 좋지만 지금은 SELECT을 계속 사용한다고 가정합니다. 예 : 하나 ExecuteScalar 모두를 수행하기 위해 다음

INSERT dbo.Orders(CustomerID,OrderDate) SELECT @CustomerID,@OrderDate; 
SELECT ID = SCOPE_IDENTITY(); 

, 대신 삽입에 대한 ExecuteNonQuery()은 다음 SELECT @@IDENTITY에 대해 별도의 명령, 당신은 단지 필요합니다.

TVP를 사용하면 주문 및 모든 세부 행을 단일 저장 프로 시저로 보낼 수 있으므로 이보다 훨씬 더 나은 작업을 수행 할 수 있습니다. 그러나 CE는 TVP를 지원하는지 확실치 않습니다. Express/LocalDB 사용을 고려해야합니다.

+0

Scope_identity는 SQL Server Compact에서 사용할 수 없으며 유일한 옵션은 @@ identity이며 동일한 연결에 대해 두 번째 선택을 실행하는 것이 중요하며 명령 당 하나의 명령문 만 허용됩니다 – ErikEJ