SQL server 通過存儲過程實現全庫數據修改 (全庫搜索 需要修改的數據)

修改一批數據、無法斷定存在於哪個表中、
大體情況如下:
這裏寫圖片描述

odata列爲舊數據、需要修改的數據
ndata列爲新數據、更新後的數據
需要將全庫所有內容爲odata列的數據更新爲ndata列
無法斷定具體哪張表存在相同數據、


創建存儲過程查找需要修改的字段


creat PROCEDURE [dbo].[proc_uptmp_ywsj]

AS
    BEGIN
        SET NOCOUNT ON;

    --變量定義
    --計算過程執行時長
        DECLARE @starttime DATETIME;
        DECLARE @totaltime INT;
    --流程控制(成功失敗)
        DECLARE @Result INT;
    --執行影響行數
        DECLARE @ROW INT;
    --錯誤日誌
        DECLARE @ErrorMessage VARCHAR(1000);

    --變量賦值
        SET @starttime = GETDATE();
        SET @Result = 0;

    --創建臨時表
        CREATE TABLE #tmp_pdchg_z
            (
              table_name VARCHAR(100) ,
              filed_name VARCHAR(100)
            );

     --全庫篩選可能存在需修改數據的列、數據類型等條件根據實際情況選擇
        INSERT  INTO #tmp_pdchg_z
                ( table_name ,
                  filed_name
                )
                SELECT  a.table_name ,
                        a.filed_name
                FROM    ( SELECT    d.name table_name ,
                                    a.colorder 字段序號 ,
                                    a.name filed_name ,
                                    ( CASE WHEN COLUMNPROPERTY(a.id, a.name,
                                                              'IsIdentity') = 1
                                           THEN '√'
                                           ELSE ''
                                      END ) 標識 ,
                                    ( CASE WHEN ( SELECT    COUNT(*)
                                                  FROM      sysobjects
                                                  WHERE     ( name IN (
                                                              SELECT
                                                              name
                                                              FROM
                                                              sysindexes
                                                              WHERE
                                                              ( id = a.id )
                                                              AND ( indid IN (
                                                              SELECT
                                                              indid
                                                              FROM
                                                              sysindexkeys
                                                              WHERE
                                                              ( id = a.id )
                                                              AND ( colid IN (
                                                              SELECT
                                                              colid
                                                              FROM
                                                              syscolumns
                                                              WHERE
                                                              ( id = a.id )
                                                              AND ( name = a.name ) ) ) ) ) ) )
                                                            AND ( xtype = 'PK' )
                                                ) > 0 THEN '√'
                                           ELSE ''
                                      END ) 主鍵 ,
                                    b.name 類型 ,
                                    a.length 佔用字節數 ,
                                    COLUMNPROPERTY(a.id, a.name, 'PRECISION') AS 長度 ,
                                    ISNULL(COLUMNPROPERTY(a.id, a.name,
                                                          'Scale'), 0) AS 小數位數 ,
                                    ( CASE WHEN a.isnullable = 1 THEN '√'
                                           ELSE ''
                                      END ) 允許空 ,
                                    ISNULL(e.text, '') 默認值 ,
                                    ISNULL(g.[value], ' ') AS [說明]
                          FROM      syscolumns a
                                    LEFT JOIN systypes b ON a.xtype = b.xusertype
                                    INNER JOIN sysobjects d ON a.id = d.id
                                                              AND d.xtype = 'U'
                                                              AND d.name <> 'dtproperties'
                                    LEFT JOIN syscomments e ON a.cdefault = e.id
                                    LEFT JOIN sys.extended_properties g ON a.id = g.major_id
                                                              AND a.colid = g.minor_id
                                    LEFT JOIN sys.extended_properties f ON d.id = f.class
                                                              AND f.minor_id = 0
                          WHERE     b.name IS NOT NULL
                                    AND d.name IN (
                                    SELECT  name
                                    FROM    sysobjects
                                    WHERE   xtype = 'U'
                                            AND name NOT LIKE '%API%'
                                            AND name NOT LIKE '%Workflow%'
                                            AND name NOT LIKE '%Membership%'
                                            AND name NOT LIKE '%LOG%' )
                        ) a
                WHERE   a.主鍵 =''
                        AND a.默認值 =''
                         AND a.類型 ='varchar'
                          OR  a.類型 = 'nvarchar';
            --SELECT *
            --FROM #tmp_pdchg_z

        DECLARE @tb_f_yj VARCHAR(500);
        DECLARE @table_name VARCHAR(50);
        DECLARE @filed_name VARCHAR(50);
        DECLARE @T TABLE ( cc VARCHAR(20) );
     --開啓事務
     --   BEGIN TRAN;
     --   BEGIN TRY
     -----遊標循環判斷可能存在需修改數據的列是否存在需修改數據
            DECLARE tb_f_cursor CURSOR
            FOR
                SELECT  'SELECT top 1 ' + filed_name + ' FROM ' + table_name
                        + ' a  WHERE   EXISTS (SELECT 1 FROM tmp_ywsj WHERE odata=a.'
                        + filed_name + ' );' ,
                        table_name ,
                        filed_name
                FROM    #tmp_pdchg_z;
            OPEN tb_f_cursor;
            FETCH NEXT   FROM tb_f_cursor INTO @tb_f_yj, @table_name,
                @filed_name;
            WHILE @@fetch_status = 0
     --計算邏輯
                BEGIN
                    INSERT  INTO @T
                            EXEC ( @tb_f_yj
                                );

                    IF EXISTS ( SELECT  1
                                FROM    @T )
                 ---將實際存在需修改數據的表名、列名插入表中
                        BEGIN 
                            INSERT  INTO uptmp_ywsj
                            VALUES  ( @table_name, @filed_name );
                        END;

                    DELETE  FROM @T;

                    FETCH NEXT FROM tb_f_cursor INTO @tb_f_yj, @table_name,@filed_name;
                END;    
            CLOSE tb_f_cursor;
            DEALLOCATE tb_f_cursor;


     --計算總時長
            SET @totaltime = DATEDIFF(SECOND, @starttime, GETDATE());

        --END TRY
        --BEGIN CATCH

        --    IF @@TRANCOUNT > 0
        --        BEGIN
        --            ROLLBACK TRAN;
        --            SELECT  @ErrorMessage = '操作發生異常:'
        --                    + CAST(ERROR_NUMBER() AS VARCHAR) + ','
        --                    + ERROR_MESSAGE() ,
        --                    @Result = -1;
        --        END;

        --END CATCH;

        --IF @@TRANCOUNT > 0
        --    AND @Result = 0
        --    BEGIN
        --        COMMIT TRAN;
        --    END;

        --IF @@TRANCOUNT > 0
        --    AND @Result <> 0
        --    BEGIN
        --        ROLLBACK TRAN;
        --    END;

    --SELECT @b AS b;

    --刪除臨時表
        IF EXISTS ( SELECT  *
                    FROM    tempdb..sysobjects
                    WHERE   id = OBJECT_ID('tempdb..#tmp_aa') )
            BEGIN
                DROP TABLE #tmp_aa;
            END;

    --記錄日誌
   --INSERT INTO tb_SYSLOGS(Logger,Logtime,LogIP,Logname,LogTotalTime,LevelCode,Message,LogSQL)
   --     SELECT  'Templete' ,
   --             GETDATE() ,
   --             '::1' ,
   --             'sa' ,
   --             @totaltime ,
   --             'proc_uptmp_pdchg' ,
   --             '' ,
   --             '影響行數' + CAST(@ROW AS VARCHAR(10)) + ',' + @ErrorMessage;

    END;

備註: 其中
a.主鍵 =”
AND a.默認值 =”
AND a.類型 =’varchar’
OR a.類型 = ‘nvarchar’
根據實際情況篩選


創建此過程中需要用到的表

------存放需修改數據的表
CREATE TABLE [dbo].[tmp_ywsj](
    odata [varchar](100) NULL,
    ndata [varchar](100) NULL
) ON [PRIMARY] ;

-----創建表用於存放數據庫中實際需修改的列
CREATE TABLE uptmp_ywsj
    (table_name VARCHAR(100),
     filed_name VARCHAR(100));

執行存儲過程

EXEC proc_uptmp_ywsj 

實際需修改的列會寫入uptmp_ywsj表中


根據uptmp_ywsj 生成update腳本

SELECT 
'CREATE NONCLUSTERED INDEX [NON-'+table_name+'_'+filed_name+'] ON '+table_name+' ('+filed_name+');',

'UPDATE SET A.'+filed_name+' = B.ndata, a.UpdatedAt = GETDATE() FROM dbo.'+table_name+' A, dbo.tmp_ywsj B WHERE B.odata = a.'+filed_name+';' ,

'DROP INDEX [NON-'+table_name+'_'+filed_name+'] ON  dbo.'+table_name+';'

 FROM uptmp_ywsj

執行查詢結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章