2017-03-03 6 views
0

SQL 테이블에서 Start_Date, End_Date 및 IsActive 열이 있습니다.일정한 간격마다 SQL 테이블 열을 업데이트하는 방법은 무엇입니까?

모든 삽입에는 Start_Date, End_Date의 Null 및 IsActive의 유효한 날짜 시간 항목이 있습니다.

30 분이 지나면 End_Date를 현재 날짜 시간으로 업데이트하고 IsActive를 1로 업데이트해야합니다. 이것은 SQL Express에 있습니다. 작업 스케줄러를 사용할 수 없습니다. Windows 작업 스케줄러를 사용하지 않는 것이 좋습니다.

트리거에는 삽입 또는 업데이트 후 제한 사항이 있습니다. 이 문제를 처리 할 수있는 방법이 있습니까?

+1

왜 스케줄러를 사용할 수 없습니까? 여기에는 두 가지 선택 사항이 있습니다. 삽입하는 동안 값을 설정하거나 예약 된 작업을 사용하십시오. 슬프게도 이것은 조금 기괴합니다. 왜 30 분 만에 맹목적으로 End_Date를 업데이트합니까? 그건 말이 안돼. 그것은 단지 그것이 작동 했음에 틀림 없다고 가정합니다. 행이 만들어 질 때 나중에이 값을 30으로 설정하는 것보다이 방법이 더 좋은 방법일까요? –

+0

대화 타이머 (https://msdn.microsoft.com/en-us/library/ms187804.aspx)와 함께 Service Broker 대기열 활성화 저장 프로 시저를 사용할 수 있습니다. –

+0

해당 레코드 행에 대해 30 분을 사용하는 논리입니다. 30 분 후에 레코드 행은 비활성 상태가됩니다. 그래서 end_date 타임 스탬프를 설정해야합니다 – goofyui

답변

1

아래 예제는 서비스 브로커 활성화 저장 프로 시저 및 대화 타이머를 사용하여 정기적으로 테이블을 업데이트합니다. DialTimer 메시지를 받으면 활성화 된 dbo.UpdateSqlTableOnTimer proc은 테이블을 업데이트하고 새 타이머를 시작합니다. dbo.StartUpdateSqlTableOnTimer proc는 초기 타이머를 시작하고 대화 핸들을 반환합니다. 필요한 경우 dbo.StopUpdateSqlTableOnTimer 핸들을 지정하여 타이머 루프를 중지합니다.

데이터베이스에는 서비스 브로커가 활성화되어 있어야합니다. 아직 활성화되어 있지 않은 경우 ALTER DATABASE을 사용하여 서비스 브로커를 활성화하십시오.

ALTER DATABASE YourDatabase 
    SET ENABLE_BROKER; 

USE YourDatabase; 
GO 

CREATE PROC dbo.StartUpdateSqlTableOnTimer 
--begin initial conversation and timer 
AS 
DECLARE @ConversationHandle uniqueidentifier; 
BEGIN DIALOG CONVERSATION @ConversationHandle 
    FROM SERVICE UpdateSqlTableOnTimer 
    TO SERVICE 'UpdateSqlTableOnTimer', 'CURRENT DATABASE' 
    ON CONTRACT [DEFAULT] 
    WITH ENCRYPTION = OFF; 
BEGIN CONVERSATION TIMER (@ConversationHandle) 
    TIMEOUT = 1800; 
SELECT @ConversationHandle AS ConversationHandle; 
GO 

CREATE PROC dbo.StopUpdateSqlTableOnTimer 
    @ConversationHandle uniqueidentifier 
--end conversation 
AS 
END CONVERSATION @ConversationHandle; 
GO 

CREATE PROC dbo.UpdateSqlTableOnTimer 
AS 

SET XACT_ABORT ON; 
SET NOCOUNT ON; 

DECLARE 
     @ConversationHandle uniqueidentifier 
    , @MessageTypeName sysname 
    , @EventNotificationDetails xml 
    , @EventLogMessage nvarchar(MAX); 

BEGIN TRY 

    BEGIN TRAN; 

    RECEIVE TOP(1) 
      @ConversationHandle = conversation_handle 
     , @MessageTypeName = message_type_name 
     , @EventNotificationDetails = CAST(message_body AS xml) 
    FROM dbo.QueueForUpdateSqlTableOnTimer; 

    IF @@ROWCOUNT > 0 
    BEGIN 

     IF @MessageTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer' 
     BEGIN 

      --update IsActive and End_Date here 

      --start new timer 
      BEGIN CONVERSATION TIMER (@ConversationHandle) 
       TIMEOUT = 1800; 
     END 
     ELSE 
     BEGIN 
      IF @MessageTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' 
      BEGIN 
       END CONVERSATION @ConversationHandle; 
      END 
      ELSE 
      BEGIN 
       END CONVERSATION @ConversationHandle WITH ERROR = 1 DESCRIPTION = 'Unexpected message type received'; 
      END; 
     END; 

    END; 

    COMMIT; 

END TRY 
BEGIN CATCH 

    IF @@TRANCOUNT > 0 ROLLBACK; 
    THROW; 

END CATCH; 
GO 

--create queue with proc activation 
CREATE QUEUE dbo.QueueForUpdateSqlTableOnTimer 
    WITH STATUS=ON, 
    ACTIVATION (
     PROCEDURE_NAME = dbo.UpdateSqlTableOnTimer, 
     MAX_QUEUE_READERS = 1, 
     EXECUTE AS OWNER) ; 
GO 

CREATE SERVICE UpdateSqlTableOnTimer 
    ON QUEUE dbo.QueueForUpdateSqlTableOnTimer 
    ([DEFAULT]); 
GO 

EXEC dbo.StartUpdateSqlTableOnTimer; 
GO 

EXEC dbo.StopUpdateSqlTableOnTimer @ConversationHandle = '<specify value from dbo.StartUpdateSqlTableOnTimer>'; 
GO 
+0

예제를 공유해 주셔서 감사합니다. 우리의 논리가 바뀌었지만 ... 서비스 브로커 및 대화 타이머 예제를 공유해 주셔서 정말 감사드립니다. – goofyui