2017-12-11 14 views
0

ms ms 데이터베이스에서 테이블 번호 콤보 여러 삽입, 업데이트 및 삭제가 발생할 수 있습니다 (단 하나뿐 아니라 물론). 이라는 다른 테이블에서 migrimi_temp 나는 동일한 형태의 결과를 얻기 위해 mysql에서 실행되어야하는 쿼리의 형태로 이러한 변경 사항을 추적합니다.삽입 트리거로 인해 쿼리 실행이 끊어집니다.

예를 들어, 삭제 쿼리 ID> (50)는, 트리거가 로그 테이블에 다음 쿼리를 저장하도록 활성화되어야하는 모든 행에 대해 수행되는 경우 :

콤보에서 삭제 여기서 ID> 50;

따라서이 콤보 테이블의 삭제 쿼리는 로그 테이블에 한 행을 생성합니다.

대신 삽입 쿼리에 2 개의 행을 삽입하면 트리거가 활성화되어 각 삽입을 로그 테이블에 저장해야합니다. 따라서이 콤보 표의 삽입 쿼리는 로그 테이블에 2 개의 새 행을 생성합니다.

필자는 분리 된 트리거에 삽입, 업데이트 및 삭제 작업을 처리하려고합니다. 단일 행 삽입/업데이트/삭제를위한 트리거를 작성했습니다. 그런 다음 여러 가지 행동이 수행 될 수도 있습니다.

이것은 단일 쿼리에서 여러 삽입의 경우를 처리하려는 나의 시도입니다. 나는 커서없이 초기 트리거를 적용 할 수없는 커서를 사용했다. 트리거가 성공적으로 실행되었지만 삽입 (단일 또는 다중 행)을 수행하면 실행이 무한정 중단되거나 적어도 합리적인 것보다 오래 걸립니다.

USE [migrimi_test] 
GO 
/****** Object: Trigger [dbo].[c_combo] Script Date: 12/11/2017 5:33:46 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
create TRIGGER [dbo].[u_combo] 
ON [migrimi_test].[dbo].[combo] 
AFTER INSERT 
AS 
BEGIN 

    SET NOCOUNT ON 
    DECLARE @c_id INT; 
    DECLARE @c_name nvarchar(100); 
    DECLARE @c_duration int; 
    DECLARE @c_isavailable INT; 

    DECLARE c CURSOR FOR 
     SELECT id, name, duration, isvisible FROM inserted 
    OPEN c 
    FETCH NEXT FROM c INTO @c_id, @c_name, @c_duration, @c_isavailable 
    WHILE @@FETCH_STATUS = 0 

    INSERT INTO [migrimi_temp].[dbo].[sql_query] (query) 
    VALUES ('INSERT INTO combo (id, name, duration, value, isavailable, createdAt, updatedAt) values ('+CAST(@c_id as nvarchar(50))+', '+'"'[email protected]_name+'"'+', 
    '+CAST(@c_duration as nvarchar(50))+', 1, '+CAST(@c_isavailable as nvarchar(50))+', Now(), Now());') 

    FETCH NEXT FROM c INTO @c_id, @c_name, @c_duration, @c_isavailable 
    CLOSE c 
    END 
    DEALLOCATE c 

GO 

SQL 서버 버전은 (나는 그와 관련이 의심하지만) 2012 OS는 윈도우 서버 2008입니다. 나는 주로이 두 가지 자원을 기반으로했다 : https://social.msdn.microsoft.com/Forums/sqlserver/en-US/40f5635c-9034-4e9b-8fd5-c02cec44ce86/how-to-let-trigger-act-for-each-row?forum=sqlgetstarted

How can I get a trigger to fire on each inserted row during an INSERT INTO Table (etc) SELECT * FROM Table2?

이 내가 달성하기 위해 노력하고 더 큰 생각의 일부이며,이 때까지 일 전 트리거와 완전히 익숙했다. 나는 합리적인 시간에 학습을 균형 잡기 위해 노력하고 있지만 그렇게하지는 마십시오.

+0

충분한 코드로이 작업을 수행 할 수 있습니다. 나는 도움을 줄 수는 없지만 트리거 (위대한 관행은 아님) 내부에 커서를 놓으면 (모범 사례는 아니지만) 많은 상심과 나쁜 수행으로 이어질 것이라고 생각합니다. – dfundako

답변

0

커서가 SQL 서버에서 악명 높게 느립니다. 커서를 사용하여 삽입 된 테이블을 반복하는 대신 집합 기반 방식 인 insert...select을 사용할 수 있습니다. 훨씬 빠르며 SQL에서 작업하는 데 권장되는 방법입니다.

CREATE TRIGGER [dbo].[u_combo] 
ON [migrimi_test].[dbo].[combo] 
AFTER INSERT 
AS 
BEGIN 

    INSERT INTO [migrimi_temp].[dbo].[sql_query] (query) 
    SELECT 'INSERT INTO combo (id, name, duration, value, isavailable, createdAt, updatedAt) values ('+CAST(id as nvarchar(50))+', "'+ name +'", 
     '+ CAST(duration as nvarchar(50)) +', 1, '+ CAST(isvisible as nvarchar(50))+ ', Now(), Now());' 
    FROM inserted  

END 

GO 
+0

나는 노래하는 커서가 꽤 나쁜 생각처럼 보인 것에 동의합니다. 처음에는 이런 식으로 시도했지만 어딘가에 잘못된 문법이 생겨서 모든 행을 반복하지 않을 것이라고 생각하게되었습니다. –

+0

도와 줘서 기쁩니다 ;-) –