2014-02-07 4 views
-3

Microsoft SQL Server에서 작업하고 있는데 테이블에 새 데이터를 삽입하려고하지만 내 데이터가 과거에 실수로 한 번 삽입 된 경우 데이터베이스에 문제가 있습니다. 그러한 재 삽입은 중요한 위반을 일으킬 수 있습니다. 내가 필요한 데이터를 삽입하고 실수로 이미 포함 된 것을 업데이트하는 방법을 찾고 있습니다.SQL 삽입 및 업데이트

BEGIN TRANSACTION 

INSERT INTO dbs_salesinternals.acc_saleshistory 
SELECT a, 
     b AS n 
FROM dbs_sales.orders AS O 
     INNER JOIN dbs_salesinternals.acc_report_months AS ARM 
       ON ARM.acc_report_month_id = dbo.Reportmonth(CASE 
          WHEN O.ordertypeid = 2 THEN shipduedate 
          ELSE shipdate 
                  END) 
     INNER JOIN dbo.contactfullnames 
       ON O.customerid = dbo.contactfullnames.contact_id 
     INNER JOIN dbs_sales.ordertypes 
       ON dbs_sales.ordertypes.ordertypeid = O.ordertypeid 
     LEFT JOIN(SELECT OD.orderid, 
         Sum(CASE 
           WHEN PB.format LIKE '%kit%' 
            AND units.curriculumcode = 'CUR' THEN 
           OD.price 
           ELSE 0 
          END) AS KitPart, 
         Sum(CASE 
           WHEN PB.format = 'PD' 
            AND units.curriculumcode = 'CUR' THEN 
           OD.price 
           ELSE 0 
          END) AS PDPart, 
         Sum(CASE 
           WHEN (PB.format <> 'PD' 
            AND PB.format NOT LIKE '%kit%' 
            AND units.curriculumcode = 'CUR') THEN 
           OD.price 
           ELSE 0 
          END) AS OtherPart, 
         Sum(CASE 
           WHEN PB.format LIKE '%kit%' 
            AND units.curriculumcode = 'WEB' THEN 
           OD.price 
           ELSE 0 
          END) AS EKitPart, 
         Sum(CASE 
           WHEN PB.format = 'PD' 
            AND units.curriculumcode = 'WEB' THEN 
           OD.price 
           ELSE 0 
          END) AS EPDPart, 
         Sum(CASE 
           WHEN (PB.format <> 'PD' 
            AND PB.format NOT LIKE '%kit%' 
            AND units.curriculumcode = 'WEB') THEN 
           OD.price 
           ELSE 0 
          END) AS EGuidePart 
       FROM dbs_salesinternals.eieproductsbase AS PB 
         INNER JOIN dbs_salesinternals.productpricing AS PP 
           ON PB.productid = PP.product_id 
         INNER JOIN dbs_sales.[order details] AS OD 
           ON PP.productpricing_id = OD.productpricing_id 
         INNER JOIN units 
           ON PB.unit_id = units.unit_id 
       GROUP BY OD.orderid) OP 
       ON OP.orderid = O.orderid 
     LEFT JOIN [dbo].[grant_codes] 
       ON [dbo].[grant_codes].grantcodemap_id = O.accountcode 
WHERE O.ordertotal <> 0 
     AND O.ordertypeid IN (1, 2, 3, 4) 
     AND ARM.acc_report_month_id = 166 
     AND ([dbo].[grant_codes].granttype IS NULL 
       OR [dbo].[grant_codes].granttype <> 2) 

COMMIT TRANSACTION 

어떻게 내가 필요한 것을 달성하기 위해이를 변경할 수 있습니다 : 그것은 지금의 약자로 코드의 내역 중 일부는 간결 변경하지만 내 코드 되었는가?

+1

MERGE를 조사해야하는 것처럼 들립니다. http://msdn.microsoft.com/en-us/library/bb510625.aspx –

+0

질문을 편집하고 모든 것을 굵게 표시하여 서식에서 제거 할 수 있습니다 도움이 안돼. –

+0

옙 병합은 매우 유용한 도구가 될 수 있습니다. –

답변

0

나는 그것이 더 좋을 수도 코멘트에 언급 된 병합 도구를 사용하지만, 여기에 내가 어떻게 할 것입니다하지 않은 :

첫째, 임시 테이블에 삽입 무언가로 기존 쿼리를 변경 (임시 테이블은 그 이름 앞에 #)로 표시됩니다 :

select <your select-clause> 
into #temp 
from <your from-clause> 
where <your where-clause> 

그래서 지금 우리는이 개 테이블을 모두 포함하는 데이터를. 추가 할 테이블을 S이라고하고, 임시 테이블을 추가 할 데이터의 기초로 사용할 테이블을 T이라고합시다.

먼저 T의 행 중 어떤 것이 이미 S에 있는지 알아야합니다. 그들은 아마의이 id를 호출하자, 공통의 행 식별자를 가지고 있고, 참여 간단한 통해 S에 해당 행이 T의 행 세트를 찾을 수 :

select * from S s join T t on s.id = t.id; 

행이 쿼리에서 반환되는 행입니다 우리는 업데이트하고 싶다. 이렇게하려면,이 유형의 쿼리를 사용할 수 있습니다

update S 
set c1 = (select t.c1 from T t where t.id = S.id), 
c2 = (select t.c2 from T t where t.id = S.id), 
... 
cN = (select t.cN from T t where t.id = S.id) 
where S.id in (
    select t.id 
    from S s join T t on s.id = t.id); 

우리는 TS 모두에 존재 S의 모든 행을 업데이트하고, 내부 선택과 T의 값을 "선택".

다음으로 T에 행을 삽입해야합니다.이 행은 이미 S에 없습니다. 이 쿼리는 것을 할 것입니다 :

insert into S (id, c1, c2, ..., cN) 
select id, c1, c2, ..., cN 
from T where id not in (select id from S); 

합니다 (where -clause에 조인을 사용할 수도 있지만, 이것은 단지뿐만 아니라 작동합니다 ..)

이미되지 않은 T의 행을 삽입합니다이 쿼리 SS.