2016-02-17 117 views
0

我們有一個每小時運行一次的存儲過程,需要大量修改。在存儲過程運行時有人會編輯它,並導致存儲過程中斷和結束。我正在尋找一個錯誤,當有人在運行時嘗試編輯存儲過程時彈出,而不是中斷執行。如何在存儲過程運行時防止SQL存儲過程更改?

這是一個每小時運行一次的sql服務器代理作業,我得到「對象'stored_procedure'的定義在編譯後發生了變化。」

有什麼我可以添加到程序?一個設置?

+0

您是否沒有可以使用的其他數據庫副本? –

+0

當你改變運行程序時會發生什麼?它肯定不應該阻止正在執行的客戶端完成 –

+0

這是一個每小時運行一次的工作,我得到「對象'stored_procedure'的定義在編譯後發生了變化。」 –

回答

0

你應該做一些研究和測試,並確認是這種情況。在執行時更改SProc不應影響運行。

打開兩個SSMS窗口並首先運行查詢1並切換到窗口2並運行該查詢。

查詢1

CREATE PROCEDURE sp_altertest 
AS 
BEGIN 

SELECT 'This is a test' 

WAITFOR DELAY '00:00:10' 
END 
GO 

EXEC sp_altertest 

QUERY2

alter procedure sp_altertest AS 

BEGIN 

SELECT 'This is a test' 

WAITFOR DELAY '00:00:06' 
END 
GO 
Exec sp_altertest 

查詢1應繼續運行,並有一個10秒的執行時間,而查詢2將與6秒運行時運行。 SProc在運行時被緩存並存儲在內存中。改變應該沒有影響。

+0

需要注意的是,如果人們正在修改基礎表,那麼在執行sproc之前,您可能需要引入sp_recompile。 – dfundako

+0

謝謝,我也認爲是這樣。這是一個SQL服務器代理作業,我得到這個錯誤「對象'stored_procedure'的定義在編譯後發生了變化。」 –

1

我認爲你可以在數據庫級別,以防止更改使用觸發器和對象中應用驗證的運行存儲過程是這樣的:

USE [YourDatabase] 
GO 


ALTER TRIGGER [DDLTrigger_Sample] 
    ON DATABASE 
    FOR CREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE 
AS 
BEGIN  
    IF EXISTS (SELECT TOP 1 1 
        FROM sys.dm_exec_requests req 
        CROSS APPLY sys.dm_exec_query_plan(req.plan_handle) sqlplan WHERE sqlplan.objectid = OBJECT_ID(N'GetFinanceInformation')) 
    BEGIN 
     PRINT 'GetFinanceInformation is running and cannot be changed' 
     ROLLBACK   
    END 
END 

這樣就可以防止存儲程序在執行過程中被改變,如果沒有被執行,改變將如常反映。希望這可以幫助。