Articles

Using INSERT OUTPUT in a SQL Server Transaction

By: Tim Ford | Updated: 2010-12-13 | Comments (6) | Related: More > T-SQL

Development Best Practices for SQL Server

Free MSSQLTips Webinar: Development Best Practices for SQL Server

Attend this webinar to learn about development best practices for SQL Server. 앤디 워렌 공유할 것입니다 그의 많은 수년간의 경험을 제공 몇 가지 포인터에 무슨 일이 그를 위해 최선 방법을 활용할 수 있는 이 지식의 일부.

문제

자주 나는 나 자신을 발견 상황에서 필요 레코드를 삽입 테이블에는 설정를 기반으로 작동하고 감싸 안는 트랜잭션으로,그리고 같은 트랜잭션 내에서,나는 부활-off 후속 삽입 관련 테이블 어디를 전달해야에서 키 값의 결과 초기 삽입 명령입니다. SQL Server 의 Transact/SQL 향상 덕분에이 작업은 훨씬 쉬워졌으며 단일 명령문으로 수행 할 수 있습니다… 방아쇠없이!

솔루션

Microsoft SQL Server 의 Transact/SQL 향상 중 하나는 INSERT 문의 출력 하위 절입니다. 당신이 할 수있는 기록을 삽입을 통해 INSERT(도 생각할 수 있을 캡처 정체성에 대한 열 값을 새로운 행)이후 사용을 위해서는 추가로 삽입하는 문의에 대해 자식 테이블을 유지 참조 무결성에 대한 필요없이 삽입니다. 왜 그냥 트리거를 사용하지 않습니까? 그것은 sql Server 의 실행 가능하고 입증 된 구조입니다,그렇죠?

짧은 대답은”예,그렇습니다.”그러나 트리거는 데이터베이스가 유지하는 불쾌한 작은 비밀 중 하나입니다. 그들은 단지 당신에게 바로 뛰어 들고”여기 있습니다!”예를 들어 가지고 문제 해결 프로세스의 교착 상태 또는 조정을 제대로 수행하는 쿼리-트리거에 앉아 배경으로 수행의 요구하는 원인이 될 수도 있는 문제지만,당신이 가고 가을 통해 많은 반복을 찾을 저장되는 절차,그리고 ad-hoc T/SQL 코드기 전에 당신은 아마도 중지 고려해 트리거가있는 발사 데이터를 수정하는 명령어(DML)-삽입 업데이트하거나 삭제하는 것은 겸임 당신이 무엇을 하려고 진단할 수 있습니다. 내가 연결을 사용의 트리거를 사용하여 ad-hoc T/SQL 사용되는 코드에서는 응용 프로그램의 코드를 스택과 전달되는 SQL 서버 인스턴스에 대한 처리-관행에 부끄러워하로 떨어져 있습니다.

이것이 내가 삽입 출력 구조로 보는 것을 좋아하는 이유입니다. 당신의 혜택을 얻을 캡처 할 수있는 삽입되는 값을 전달할 수 있습을 보조하는 명령과할 수 있는 포장이 모든 내부의 하나의 트랜잭션에 대한 원자성입니다. 이 구조의 구문은 아래에 나와 있으며 기본 삽입 T/SQL 명령과 약간 다릅니다:

INSERT INTO SOME_TABLE>
(
column_list>
)
OUTPUT INSERTED.identity_column>--기타 열 SOME_TABLE 필요하다면
로 SOME_OTHER_TABLE>
(
다>
)
SELECT
(
다>
)
에서 source_table_OR_JOIN_of_multiple_tables>
어디 filtering_criteria>

사이의 유일한 차이점이고 표준 INSERT 문은 포함에서 출력됩니다…성명서로. 을 만들이 쉽게 그것의 생각으로 단순히 보조를 삽입 문의 내부에는 원래 INSERT 캡처하는 값에서 가상화된 삽입 테이블 동 테이블 트리거를 사용하는 것-프로세스 보조 삽입하는 또 다른 표입니다. 아래 예에서,그리고서 유지와 함께 휴가 시즌에 당신이에 대한 책임의 비트를하고 있 채용하고 있기 때문에 기업 AdventureWorks 소가 있습니다. 오른쪽 유쾌한 오래 된 엘 프 일부 매장 프로 모션에 대 한 고용 되 고 기업 정책 유지에 당신은 항상 수행 90 어떤 새로운 고용에 대 한 일 검토. 우리는 새로운 고용이 인적 자원의 부분에 대한 추가 작업없이 입력 될 때 notfication 을 기록하기를 원합니다. 아래 코드는 INSERT-OUTPUT 을 사용하여이 작업을 수행 할 수있는 방법을 시연합니다.

이 예제에서;
GO
---만들기를 들어 테이블을
/*
참고,이것은 완전히 정상화됩니다. 이것이 실제 해결책이라면 알림 유형에 대해 다른 테이블
을 포함 시켰을 것입니다.
또한 Varchar(xx)NotificationType 열 대신 Notificationtypeid 열을 Notificationtable
에서 사용합니다.
*/
스키마 권한 부여 dbo 만들기;
GO
테이블을 만듭니다.
(
IDENTITY(1,1)NOT NULL,
VARCHAR(30)NOT NULL,
VARCHAR(30)NOT NULL,
제약 기본 키가 클러스터 된
(
ASC
)ON
)ON;
테이블을 만듭니다.
(
ID(1,1)NULL 이 아닌
NULL 이 아닌
DATETIME NULL 이 아닌
VARCHAR(30)NULL 이 아닌
기본 제약 조건 키 클러스터
(
ASC
)에
)로;

이제는 우리가 내장하는 개체에 대한 이 작은 운동이 우리가 볼 수 있습니다 삽입-산출 구성에서 작업입니다…

/*
직원에게 추가 된 키 값을 삽입 할 수있는 방법을 보여줍니다.알림에 StaffID
.Staffid in single transaction
*/
INSERT INTO HR.Staff(FirstName,LastName)
OUTPUT INSERT.StaffID,DATEADD(d,90,GETDATE()),'90-Day 리뷰'
으로 HR.알림
(
StaffID
NotificationDate
NotificationType
)
값('산타','클로스');

선택하면 지금 모두에서 직원 및 알림을 표시 키 값을 성공적으로 들어 모두의 테이블:

SELECT*FROM HR.직원;
SELECT*FROM HR.알;

Transact/SQL 개선에서 Microsoft SQL 서버 출력 sub-절 INSERT 문의

지금은 매우 중요하며 확실히 제한하기 위하여 경고를 사용하여 삽입합니다. 출력 대상은 외래 키 관계의 일부가 될 수 없습니다. 데이터베이스에서 해당 관계를 통해 다른 객체에 계단식 관계가없는 경우에도 마찬가지입니다. 의 경우 어떻게되는지 살펴 보자. 추가 외국인 핵심에 알림 StaffID,참조하 StaffID 에서 열 직원 테이블에 다음을 추가하려고 일부 추가적인 휴가 도움말:

--추가 외국에 대한 키 StaffID 열 알림 표
ALTER TABLE HR.알림을 추가 제약 조건을
외국인 핵심
(
StaffID
)
참조 HR.직원
(
StaffID
);
/*
할 수 있는 방법을 보여줍니다 삽입하는 키 값을 추가로 적립하고 있습니다.알림에 StaffID
.Staffid in single transaction
*/
INSERT INTO HR.Staff(FirstName,LastName)
OUTPUT INSERT.StaffID,DATEADD(d,90,GETDATE()),'90-Day Review'
INTO HR.Notification
(
StaffID,
NotificationDate,
NotificationType
)
VALUES('Frosty','Snowman');
SELECT*FROM HR.직원;
SELECT*FROM HR.알림;

다음과 같은 오류 메시지가 반환됩니다으로 예상된다.

Msg332,16 레벨,상태 1,17
목표 테이블'HR.알림이'등의 출력으로 절할 수 없는 하나의 측면(기본 키,외국 KEY)를 관계입니다. 참조 제약 조건'FK_Notification_Staff'를 찾았습니다.

이것은 가능성이 좋은 씨 이후이 경우에 아마 좋은 눈사람 90 일 주위에있을 것 없습니다.

다음 단계
  • 에 대해 자세히 출력 절
  • 또한 이것을 읽는 이전에 대한 정보를 산출 절
  • 더 많은 끝에서 저자는 사용을 통해 이 링크를 클릭하십시오.

최근 업데이트: 2010-12-13

얻는 스크립트

다음 끝 버튼

저자에 관하여
MSSQLTips 저자 팀 포드팀 포드 수석 데이터베이스 관리자로 MindBody.
내 모든 팁보기
관련 리소스

  • 더 많은 데이터베이스 개발자 팁…

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다