2015-04-05 130 views
0

我正在嘗試創建一個存儲過程,該存儲過程生成更新語句,以便在包含SSN列的整個事務的193個表中使用正確的SSN更新錯誤輸入的SSN。我希望這個存儲過程記錄錯誤消息,並在更新失敗的情況下回滾輸入事務。如何創建存儲過程?

我該如何解決這個問題?

我對這個練習的做法如下:如果有這樣做的有效方式,請讓我知道。我需要對我的代碼進行質量檢查。請幫忙!

CREATE PROCEDURE uspUpdateSSNErrorLog 
AS 
    SET NOCOUNT ON; 

    CREATE TABLE #UpdateSSNErrorLog 
    (
     [ErrorID] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY, 
     [ErrorNumber] [nvarchar](50) NOT NULL, 
     [ErrorDescription] [nvarchar](4000) NULL, 
     [ErrorProcedure] [nvarchar](100) NULL, 
     [ErrorState] [int] NULL, 
     [ErrorSeverity] [int] NULL, 
     [ErrorLine] [int] NULL, 
     [ErrorTime] [datetime] NULL  
    ); 

    INSERT INTO #UpdateSSNErrorLog 
    (
     ErrorNumber 
     ,ErrorDescription 
     ,ErrorProcedure 
     ,ErrorState 
     ,ErrorSeverity 
     ,ErrorLine 
     ,ErrorTime 
    ) 
    VALUES 
    (
     ERROR_NUMBER() 
     ,ERROR_MESSAGE() 
     ,ERROR_PROCEDURE() 
     ,ERROR_STATE() 
     ,ERROR_SEVERITY() 
     ,ERROR_LINE() 
     ,GETDATE() 
    ); 

    SET NOCOUNT OFF; 
    GO 

    CREATE PROCEDURE uspUpdateSSN 
    AS 

    SET NOCOUNT ON; 

DECLARE @OldSSN VARCHAR(9); 
DECLARE @NewSSN VARCHAR(9); 
DECLARE @CMD VARCHAR(400); 

-- Create the table. 
CREATE TABLE #updateSSNlist (
    Updatelist varchar(400) 
); 

INSERT INTO #updateSSNlist 
SELECT 
'UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] SET [' + Column_Name + '][email protected] WHERE [' + Column_Name + '][email protected];' 
    FROM INFORMATION_SCHEMA.COLUMNS 
WHERE Column_Name ='SSN'; 

-- Declare a cursor. 

DECLARE SSN_Update CURSOR FOR 
    SELECT * 
    FROM #updateSSNlist 

OPEN SSN_Update; 

FETCH NEXT 
FROM SSN_Update 
INTO @CMD; 

WHILE @@FETCH_STATUS = 0 
BEGIN 

BEGIN TRAN 
BEGIN TRY 
    EXEC @CMD; 
FETCH NEXT 
FROM SSN_Update 
INTO @CMD; 
COMMIT TRAN 
END TRY 

BEGIN CATCH 
    EXEC uspUpdateSSNErrorLog --To log update errors 
    ROLLBACK 
END CATCH 

CLOSE SSN_Update; 
DEALLOCATE SSN_Update; 

DROP TABLE #UpdateSSNErrorLog; 

回答

0

我會先創建一個物理表,首先創建一個表名,以便知道它出錯的表。其次,我認爲你應該立即執行所有更新。 注意:我不知道你的SSN列是INT還是VARCHAR。如果Varchar,你需要在它周圍添加引號。

嘗試了這一點:

CREATE TABLE UpdateSSNErrorLog 
(
    [ErrorID] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY, 
    [TableName] VARCHAR(100) NOT NULL, 
    [ErrorNumber] [nvarchar](50) NOT NULL, 
    [ErrorDescription] [nvarchar](4000) NULL, 
    [ErrorProcedure] [nvarchar](100) NULL, 
    [ErrorState] [int] NULL, 
    [ErrorSeverity] [int] NULL, 
    [ErrorLine] [int] NULL, 
    [ErrorTime] [datetime] NULL  
); 


DECLARE @OldSSN VARCHAR(9) = 1; 
DECLARE @NewSSN VARCHAR(9) = 2; 
DECLARE @CMD VARCHAR(MAX); 

SELECT @cmd = COALESCE(@cmd,'') + 
'BEGIN TRY 
BEGIN TRANSACTION 
    UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] SET [' + Column_Name + '] = ' + @NewSSN + ' 
    WHERE [' + Column_Name + '] = ' + @OldSSN + ' 
COMMIT TRANSACTION 
END TRY 

BEGIN CATCH 
ROLLBACK TRANSACTION; 
INSERT INTO UpdateSSNErrorLog 
(
    TableName 
    ,ErrorNumber 
    ,ErrorDescription 
    ,ErrorProcedure 
    ,ErrorState 
    ,ErrorSeverity 
    ,ErrorLine 
    ,ErrorTime 
) 
VALUES 
( ''' + Table_name + ''' 
    ,ERROR_NUMBER() 
    ,ERROR_MESSAGE() 
    ,ERROR_PROCEDURE() 
    ,ERROR_STATE() 
    ,ERROR_SEVERITY() 
    ,ERROR_LINE() 
    ,GETDATE() 
); 
END CATCH ' 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME != 'UpdateSSNErrorLog' 
     --AND Column_Name ='SSN'; 

SELECT @cmd 

----To Execute 
--EXEC(@cmd) 

您也可以添加一列以更新SSNErroLog要注意是否解決錯誤或不,或者你可以簡單地刪除一旦解決了行。

+0

如果其中一個更新語句失敗,代碼必須回滾所有事務。你能把它融入你的? – augie 2015-04-05 10:37:28

+0

是的,你說得對。試試我的新代碼。 – Stephan 2015-04-05 21:26:06