2010-07-14 4 views
2

장시간 독자, 처음 포스터 ;-)기본 키 업데이트 트리거 대신

이전 시스템을 기반으로 시스템을 구현하고 있습니다. 새 시스템은 SQL Server 2008을 사용하며 주 테이블에 새 항목을 삽입하려고 할 때 문제가 발생합니다. 이는 두 가지 방식으로 발생합니다. 기존 시스템에서 가져 오거나 (1) 새 시스템에서 생성 할 수 있습니다 (2).

(1) 항목에 이미 ID (int)가 있어야합니다. (2)의 경우 ID가 채워지지 않고 테이블의 최대 현재 값 +1 인 ID를 생성하고 싶습니다. 이것은 물론 다중 행 삽입을 위해 작동해야합니다.

필자가 볼 수있는 한 해결책은 대신에 트리거를 만드는 것이지만, 이것이 어떻게 수행되는지는 알 수 없습니다. 누구든지 나에게 힌트를 주거나 이것이 어떻게 할 수 있는지 지시 할 수 있습니까?

크리스

답변

1

INSTEAD OF 트리거는이 SQL 코드를 통해 시작할 수 있습니다.

CREATE TABLE dbo.SampleTable 
(
    ID INT, 
    SomeOtherValue VARCHAR(100) NULL 
) 
GO 

CREATE TRIGGER dbo.TR_SampleTable_Insert 
    ON dbo.SampleTable 
    INSTEAD OF INSERT 
AS 
BEGIN 

    SET NOCOUNT ON; 

    -- Inserting rows with IDs 
    INSERT INTO dbo.SampleTable (
     ID, 
     SomeOtherValue) 
    SELECT 
     ID, 
     SomeOtherValue 
    FROM 
     Inserted  
    WHERE 
     ID IS NOT NULL 

    -- Now inserting rows without IDs 
    INSERT INTO dbo.SampleTable (
     ID, 
     SomeOtherValue) 
    SELECT 
     (SELECT ISNULL(MAX(ID), 0) FROM dbo.SampleTable) 
      + ROW_NUMBER() OVER(ORDER BY ID DESC), 
     SomeOtherValue 
    FROM 
     Inserted 
    WHERE 
     ID IS NULL 

END 
GO 

INSERT INTO dbo.SampleTable 
SELECT 1, 'First record with id' 
UNION 
SELECT NULL, 'First record without id' 
UNION 
SELECT 2, 'Second record with id' 
UNION 
SELECT NULL, 'Second record without id' 
GO 

SELECT * FROM dbo.SampleTable 
GO 
+0

이전 ID와 새 ID를 함께 사용하는 것이 좋지 않다는 이전 의견에 완전히 동의합니다. – JCallico

+0

고마워요. 내가 찾고 있던 바로 그 종류의 예입니다 :-) ID의 혼합에 관해서는 단점을 보았습니다. 그러나 프로젝트는이 기술적 인 문제와 관련이없는이 접근 방식에 몇 가지 단점을 제공합니다. –

+0

기꺼이 도와 드릴 수있었습니다.그 이유는 내가 원래 요청한 것을 구현했기 때문입니다. 대신에 점을 얻기 위해 호핑을 위해 대체 접근법을 제안하는 것이 아니라 즉시 제안한 것입니다. 요즘 StackOverflow의 추세처럼 보입니다. – JCallico

1

어떻게 선택적 매개 변수로 기본 키와 함께, 귀하의 삽입을 할 수있는 저장 프로 시저를 사용하는 방법에 대한. 저장 프로 시저에서 전달되지 않을 때 기본 키를 설정할 수 있습니다.

예전 기록을 삽입하기 전에 이전 기록과 새로운 기록이 혼합되어 일치하는 경우 새 기록에 이전 기록이 삽입되므로 시나리오가 실패 할 수 있습니다. 이전 테이블의 최대 ID를 얻는 것이 좋습니다. 저장 프로 시저에서 새 기본 키를 더 큰 값 (이전 max + 1, 현재 테이블 최대)으로 설정하는 것이 좋습니다

+0

나는이 옵션을 가능성으로보고 있지만, 가능한 경우 트리거 솔루션이 더 깨끗한 것으로 나타났습니다. 그렇지 않다면 필자는 반드시 저장 프로 시저 솔루션을 사용할 것입니다. ID 충돌에 관해서 - 저는이 문제를 알고 있으며, 충돌을 일으키지 않을 정도로 충분히 큰 새로운 ID를 생성 할 것입니다 (단순함을 위해 그 부분을 남겼습니다). 적어도 내년에는 스크랩 힙을 처리 할 시스템으로 충분할 것입니다 .-) –

+0

아마도 이전 ID와 새로운 ID에 대한 귀하의 의견을 오해 한 것 같습니다. 그리고 저는 상황을 충분히 설명하지 않았다고 생각합니다. 이전 시스템은 새 항목을 계속 생성하므로 새 시스템을 생산에 적용한 후에도 이전 시스템의 ID는 계속해서 가치가 상승합니다. 모든 기능이 이식 될 때까지는 이전 시스템이 폐기됩니다. –

+0

@Chris - 맞습니다. 왜 모든 오래된 레코드를 가져올 수 없었는지 물어 보려고합니다. –

0

다른 사람들은 이러한 트리거를 작성하는 방법을 보여주었습니다.

두 가지 ID를 새 데이터베이스에 저장하는 것이 좋습니다. 각 레코드는 새 시스템에서 IDENTITY 열 또는 다른 방법으로 새 ​​ID를 가져옵니다. 또한 레코드가 다른 시스템에서 가져온 경우 OriginSystem 및 OriginID가 연결됩니다. 이렇게하면 이전 ID를 유지할 수 있습니다. 이 접근법은 데이터를 가져 오기위한 새로운 시스템을 지원할 수 있다는 추가적인 이점을 제공합니다. 다른 시스템과 데이터를 병합하거나 교환 할 때.

+0

동일한 문제가 발생하면이 문제를 해결할 수 있습니다. – JCallico

+0

의견을 보내 주셔서 감사합니다. 이 해결책이 고려되었습니다. 여기에 설명되지 않은 프로젝트의 세부 사항으로 인해 데이터 모델이 나타날 수있는 것보다 더 복잡해집니다 (예전 시스템에는 다른 백업 시스템도 처리해야 함). 이 문제에 대한 최종 해결책은 아직 결정되지 않았지만 트리거 솔루션이 가능성이있는 것으로 알고 있습니다. –