테이블에 트리거가 있는 경우 OUTPUT 절과 함께 UPDATE를 사용할 수 없습니다.
는 지금 금연inging를 하고 있습니다.UPDATE
OUTPUT
삭제:
UPDATE BatchReports
SET IsProcessed = 1
OUTPUT inserted.BatchFileXml, inserted.ResponseFileXml, deleted.ProcessedDate
WHERE BatchReports.BatchReportGUID = @someGuid
테이블에 트리거가 정의될 때까지 이 문장은 정상입니다. 나의 ★★★★★★★★★★★★★★★★★.UPDATE
스테이트먼트에 에러 334가 표시됩니다.
DML 문의 대상 테이블 'BatchReports'에 INTO 절이 없는 OUTPUT 절이 포함된 경우 트리거를 활성화할 수 없습니다.
이 문제는 SQL Server 팀의 블로그 투고에서 설명하고 있습니다.UPDATE with OUTPUT 절 – Triggers – and SQLMoreResults :
에러 메세지는 자동적으로 설명된다.
또한 다음과 같은 솔루션을 제공합니다.
응용 프로그램이 INTO 절을 사용하도록 변경되었습니다.
블로그 게시물 전체를 이해할 수 없다는 것만 빼면요.
질문 하나 할게요. ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★UPDATE
동하도 록할 ????
「 」를 참조해 주세요.
- UPDATE with OUTPUT 절 – 트리거 – 및 SQLMore Results
- MERGE 문의 타깃테이블에 규칙을 유효하게 할 수 없는 이유는 무엇입니까?
- 문에 INTO 절 오류가 없는 OUTPUT 절이 포함되어 있습니다.
가시성 경고:다른 대답은 하지 마세요.잘못된 값을 제공합니다.왜 그것이 잘못된 것인지 계속 읽어보세요.
UPDATE
OUTPUT
SQL Server 2008 R2는 SQL Server 2008 R2를 사용합니다.
UPDATE BatchReports
SET IsProcessed = 1
OUTPUT inserted.BatchFileXml, inserted.ResponseFileXml, deleted.ProcessedDate
WHERE BatchReports.BatchReportGUID = @someGuid
대상:
SELECT BatchFileXml, ResponseFileXml, ProcessedDate FROM BatchReports
WHERE BatchReports.BatchReportGUID = @someGuid
UPDATE BatchReports
SET IsProcessed = 1
WHERE BatchReports.BatchReportGUID = @someGuid
으로는 사용하지 .OUTPUT
엔티티 프레임워크 자체에서 동일한 해킹을 사용하는 만큼 나쁘지 않습니다.
바라건대.
2012년
2014년
2016년
2018년
2019년 2020년은 더 나은 구현이 될 것입니다.
업데이트: OUTPUT 사용은 유해합니다.
는 '우리끼리'를요.OUTPUT
테이블 내의 "after" 값을 취득하는 절:
UPDATE BatchReports
SET IsProcessed = 1
OUTPUT inserted.LastModifiedDate, inserted.RowVersion, inserted.BatchReportID
WHERE BatchReports.BatchReportGUID = @someGuid
그러면 SQL Server의 기존 제한("수정되지 않음")에 도달합니다.
DML 문의 대상 테이블 'BatchReports'에 INTO 절이 없는 OUTPUT 절이 포함된 경우 트리거를 활성화할 수 없습니다.
회피책 #1
할 수 있는 합니다.TABLE
the " " " 。OUTPUT
★★★★
DECLARE @t TABLE (
LastModifiedDate datetime,
RowVersion timestamp,
BatchReportID int
)
UPDATE BatchReports
SET IsProcessed = 1
OUTPUT inserted.LastModifiedDate, inserted.RowVersion, inserted.BatchReportID
INTO @t
WHERE BatchReports.BatchReportGUID = @someGuid
SELECT * FROM @t
,, 이, 이, 이, 이, 이, 이, 이, except, except, except, except, except, except, except, except, except, except, except, except, except, except, except, except, except,timestamp
테이블(일시 테이블 변수도 포함)로 이동합니다.
회피책 #2
는 몰래 있다timestamp
는 실제로는 64비트(8바이트) 부호 없는 정수입니다. 테이블 수 .binary(8)
timestamp
:
DECLARE @t TABLE (
LastModifiedDate datetime,
RowVersion binary(8),
BatchReportID int
)
UPDATE BatchReports
SET IsProcessed = 1
OUTPUT inserted.LastModifiedDate, inserted.RowVersion, inserted.BatchReportID
INTO @t
WHERE BatchReports.BatchReportGUID = @someGuid
SELECT * FROM @t
그리고 그것은 효과가 있지만, 값이 틀렸다는 것을 제외한다.
" " "RowVersion
업데이트하다
- 반환된 타임스탬프:
0x0000000001B71692
- 실제 타임스탬프:
0x0000000001B71693
는 값 「」이 있기 입니다.OUTPUT
UPDATE 스테이트먼트의 마지막과 같은 값은 표에 기재되어 있지 않습니다.
- UPDATE 문작 。
- 행 변경
- 타임스탬프가 업데이트됩니다(예: 2 → 3).
- OUTPUT이 새 타임스탬프(예: 3)를 검색합니다.
- 트리거 실행
- 행을 다시 변경하다
- 타임스탬프가 업데이트됩니다(예: 3 → 4).
- 행을 다시 변경하다
- 행 변경
- UPDATE 문이 완료되었습니다.
- OUTPUT은 3을 반환합니다(잘못된 값).
이것은 다음을 의미합니다.
- 타임스탬프는 UPDATE 스테이트먼트(4)의 끝에 존재하기 때문에 취득되지 않습니다.
- 대신 타임스탬프가 UPDATE 스테이트먼트(3)의 중간에서 취득됩니다.
- 올바른 타임스탬프를 얻을 수 없습니다.
행의 값을 변경하는 트리거도 마찬가지입니다.그OUTPUT
업데이트 종료 시점에서는 값이 출력되지 않습니다.
즉, OUTPUT이 올바른 값을 반환하는 것을 신뢰할 수 없습니다.
이 고통스러운 현실은 BOL에 기록되어 있습니다.
OUTPUT에서 반환되는 열은 INSERT, UPDATE 또는 DELETE 문이 완료된 후 트리거가 실행되기 전의 데이터를 그대로 반영합니다.
엔티티 프레임워크는 이를 어떻게 해결했습니까?
동시성을 행 합니다.NET 엔티티 프레임워크(Optimistic Concurrency) 행 버전(Rowversion).는 EF IT의 .timestamp
현재 상태를 유지합니다.
「 」는 할 수 에,OUTPUT
Microsoft 엔티티 프레임워크
회피책 #3 - 최종 - OUTPUT 절 사용 안 함
다음 값을 취득하기 위해 엔티티 프레임워크에서는 다음 문제가 발생합니다.
UPDATE [dbo].[BatchReports]
SET [IsProcessed] = @0
WHERE (([BatchReportGUID] = @1) AND ([RowVersion] = @2))
SELECT [RowVersion], [LastModifiedDate]
FROM [dbo].[BatchReports]
WHERE @@ROWCOUNT > 0 AND [BatchReportGUID] = @1
마세요OUTPUT
.
네, 경합 상황에 시달리지만 이것이 SQL Server가 할 수 있는 최선의 방법입니다.
INSERT는?
Entity Framework에서 수행하는 작업:
SET NOCOUNT ON;
DECLARE @generated_keys table([CustomerID] int)
INSERT Customers (FirstName, LastName)
OUTPUT inserted.[CustomerID] INTO @generated_keys
VALUES ('Steve', 'Brown')
SELECT t.[CustomerID], t.[CustomerGuid], t.[RowVersion], t.[CreatedDate]
FROM @generated_keys AS g
INNER JOIN Customers AS t
ON g.[CustomerGUID] = t.[CustomerGUID]
WHERE @@ROWCOUNT > 0
'아니다', '아니다', '아니다', '아니다', '아니다', '아니다'를 씁니다.SELECT
OUTPUT 을 output output output output output output output output 。
하려면 , 「」가 합니다.OUTPUT INTO ...
중간 한 후 "타깃으로 선언합니다."SELECT
것으으그
DECLARE @T TABLE (
BatchFileXml XML,
ResponseFileXml XML,
ProcessedDate DATE,
RowVersion BINARY(8) )
UPDATE BatchReports
SET IsProcessed = 1
OUTPUT inserted.BatchFileXml,
inserted.ResponseFileXml,
deleted.ProcessedDate,
inserted.Timestamp
INTO @T
WHERE BatchReports.BatchReportGUID = @someGuid
SELECT *
FROM @T
가 에 와 같이UPDATE
당신이 있는 열에 영향을 줄 수 있는 방식으로 진술 그 자체OUTPUT
-ing 그러면 결과가 유용하지 않을 수 있지만 이는 트리거의 하위 집합에 불과합니다.감사 목적을 위해 다른 테이블에 기록을 트리거하거나 트리거에 원래 행이 다시 입력된 경우에도 삽입된 ID 값을 반환하는 등 다른 경우에는 위의 기술이 정상적으로 작동합니다.
필요한 열을 모두 표 변수에 넣는 이유는 무엇입니까?기본 키만 있으면 업데이트 후 모든 데이터를 읽을 수 있습니다.트랜잭션을 사용할 때는 경주가 없습니다.
DECLARE @t TABLE (ID INT PRIMARY KEY);
BEGIN TRAN;
UPDATE BatchReports SET
IsProcessed = 1
OUTPUT inserted.ID INTO @t(ID)
WHERE BatchReports.BatchReportGUID = @someGuid;
SELECT b.*
FROM @t t JOIN BatchReports b ON t.ID = b.ID;
COMMIT;
트리거는 코드의 다른 부분을 조용히 암살할 수 있는 코드 냄새입니다.대신 저장 프로시저를 사용하십시오.출력이 하지 않습니다.따라서 Interside Of 트리거가 발생하면 INT를 사용해도 출력이 작동하지 않으며 Scope_Identity도 작동하지 않습니다.
예를 들어 다음과 같습니다.
CREATE Trigger [DI].[TRG_AJC_BeforeInsert]
On [DI].[AJC]
INSTEAD OF INSERT
As
Set NoCount on
Insert Into [DI].[AJC] (val1, date2)
From Select [val1], getDate()
출력 또는 ScopeIdentity 결과는 반환되지 않습니다.스코프 ID가 아직 생성되지 않았기 때문에 결과가 없고 OUTPUT을 읽을 때 생성되지 않았기 때문에 Output에 대한 결과가 없습니다.
네 유일한 희망은 방아쇠가 다른 테이블에 삽입하지 않는 거야그런 다음 @@identity를 사용할 수 있습니다.그러나 세션 중에 다른 테이블이 업데이트/삽입된 경우 @@Identity는 원하는 ScopedIdentity가 아닌 다른 테이블의 ID를 반환합니다.
언급URL : https://stackoverflow.com/questions/13198476/cannot-use-update-with-output-clause-when-a-trigger-is-on-the-table
'programing' 카테고리의 다른 글
목록을 목록으로 변환 (0) | 2023.04.21 |
---|---|
iPhone SDK: loadView와 viewDidLoad의 차이점은 무엇입니까? (0) | 2023.04.21 |
C#의 Excel 셀에 새 행을 프로그래밍 방식으로 삽입하려면 어떻게 해야 합니까? (0) | 2023.04.21 |
빌드 실패의 원인을 오류 또는 경고 없이 찾는 방법 (0) | 2023.04.21 |
Bash에서 두 부동소수점 숫자를 비교하려면 어떻게 해야 하나요? (0) | 2023.04.21 |