存储过程实现历史表的数据记录
1.不成熟的方案
1.对业务表的操作,已历史表的方式记录。
2.目前只支持单表 和 主从表 。不支持多表结构
2.思路 之前项目是 针对存储过程开发的。 所以 业务表 加入 历史表 ,就得通过存储过程来实现 主要用到一些处理json 的函数。 参数是通过json 传输的。
1.传入表结构 取到,用于复制表结构 ,构造 histroy 表.
2.根据插入的数据 来 数据表记录中是否存在 ,存在是更新,不存在则是插入。(操作行为)
3 第一步解析对于的数据
1 -- ============================================= 2 -- Description: <Description,> 3 --调用 4 /* 5 DECLARE @jsonStr NVARCHAR(max),@jsonStr1 NVARCHAR(max),@value NVARCHAR(MAX); 6 SET @jsonStr1= N'{"Result":[{"Name":"WILL1","socre":"124","remark":"GWSort","ID":"2","Action":"update"},{"Name":"WILL1","socre":"124","remark":"GWSort","ID":"3","Action":"update"}],"ActionName":"MDM_SetGWTypeNSort","TName":"CS_Table","apiUrls":{"DeleteUrl":"/api/sn/Common/CommonSet","AddEditUrl":"/api/sn/Common/CommonSet"}}'; 7 EXEC SP_SYS_Add_Resume @jsonStr1,'admin' 8 */ 9 -- ============================================= 10 ALTER PROCEDURE [dbo].[SP_SYS_Resume] 11 12 @jsonStr NVARCHAR(MAX),@userCode NVARCHAR(50) 13 AS 14 BEGIN 15 16 DECLARE @TableName NVARCHAR(500),@Values NVARCHAR(MAX),@ValueType INT ,@JsonResult NVARCHAR(MAX) 17 ,@DetailsJSON NVARCHAR(MAX),@ColoumnValue NVARCHAR(MAX),@countindex INT,@DetailsMainTableName NVARCHAR(500) 18 19 SET @DetailsJSON=''; 20 SET @JsonResult=''; 21 SET @TableName=''; 22 SET @Values=''; 23 SET @ValueType=0 ; 24 SET @ColoumnValue='[]'; 25 SET @countindex =0; 26 SET @DetailsMainTableName=''; 27 SET NOCOUNT ON; 28 --SET XACT_ABORT ON;--设置发生异常直接回滚 29 30 31 32 SELECT @TableName=Value 33 --FROM OPENJSON (@jsonStr) WHERE [Key]='MainTableName'--对应json 表名 34 FROM OPENJSON (@jsonStr) WHERE [Key]='MainTableName'--对应json 表名 35 36 SELECT @DetailsMainTableName=Value 37 FROM OPENJSON (@jsonStr) WHERE [Key]='DetailsMainTableName'--对应json 表名 38 -- 设置主从结构表 39 40 SELECT @DetailsJSON=Value,@Values=Value,@ValueType=Type FROM OPENJSON(@jsonStr) WHERE [Key] ='Result' 41 SELECT @ColoumnValue=Value FROM OPENJSON(@jsonStr) WHERE [Key] ='AddColumns' 42 43 IF ISNULL(@Values,'') <>'' 44 BEGIN 45 46 47 EXEC dbo.SP_SYS_Add_Resume @Values,@ValueType,@TableName,@ColoumnValue 48 -- 是否有从表 49 50 --初始化参数 51 SET @Values=''; 52 SET @ValueType=0 ; 53 SET @ColoumnValue='[]'; 54 --注:表名中 State 不要重复出现 55 56 IF(@DetailsMainTableName<>'') 57 BEGIN 58 SET @TableName= @DetailsMainTableName -- 设置表名 59 END 60 ELSE 61 BEGIN 62 SET @TableName= REPLACE(@TableName,'State','Detail') 63 END 64 65 66 SELECT @countindex=COUNT(*) FROM OPENJSON(@DetailsJSON,'$.ResultDetails') WHERE [Key]='Resultdata' 67 IF(@countindex>0) 68 BEGIN 69 SELECT @Values=Value,@ValueType=Type FROM OPENJSON(@DetailsJSON,'$.ResultDetails') WHERE [Key]='Resultdata' 70 SELECT @ColoumnValue=Value FROM OPENJSON(@DetailsJSON,'$.ResultDetails') WHERE [Key] ='AddColumns' 71 END 72 ELSE 73 BEGIN 74 SELECT @Values=Value,@ValueType=Type FROM OPENJSON(@DetailsJSON) WHERE [Key]='ResultDetails' 75 -- SELECT @ColoumnValue=Value FROM OPENJSON(@DetailsJSON,'$.ResultDetails') WHERE [Key] ='AddColumns' 76 END 77 78 IF ISNULL(@Values,'')<>'' 79 BEGIN 80 EXEC dbo.SP_SYS_Add_Resume @Values,@ValueType,@TableName,@ColoumnValue 81 END 82 83 84 END 85 86 87 88 END
第二部解析 插入数据
/* Description: [实现公用表新增] 1.解析出新增的表 2.如果是新增,查出新增的数据在插入, 否则 直接插入 3.是否存在多条记录 --调用 DECLARE @jsonStr NVARCHAR(max),@jsonStr1 NVARCHAR(max),@value NVARCHAR(MAX); SET @jsonStr1= N'{"Result":[{"Name":"WILL1","socre":"124","remark":"GWSort","ID":"2","Action":"update"},{"Name":"WILL1","socre":"124","remark":"GWSort","ID":"3","Action":"update"}],"ActionName":"MDM_SetGWTypeNSort","TName":"CS_Table","apiUrls":{"DeleteUrl":"/api/sn/Common/CommonSet","AddEditUrl":"/api/sn/Common/CommonSet"}}'; EXEC SP_SYS_Add_Resume @jsonStr1,'admin' */ ALTER PROCEDURE [dbo].[SP_SYS_Add_Resume] @Json NVARCHAR(MAX) -- josn ,@ValueType INT -- josn 类型 --1 -string 2 num 3 bool 4 arry 5 object ,@TableName NVARCHAR(500) --表名 ,@ColoumnValue NVARCHAR(MAX) AS BEGIN SET NOCOUNT ON; DECLARE @JsonResult NVARCHAR(max),@TableNameHistory NVARCHAR(500),@Sql NVARCHAR(max), @HisColoumnName NVARCHAR(MAX),@Action NVARCHAR(50),@Ids NVARCHAR(MAX),@error NVARCHAR(MAX), @altersql NVARCHAR(MAX),@sqlcolumn NVARCHAR(MAX),@sqlcolumns NVARCHAR(MAX),@sqlcolumnss NVARCHAR(MAX),@columnjson NVARCHAR(MAX),@HisColoumnNameNO NVARCHAR(MAX) SET @error=''; SET @Ids ='' --ID SET @Action ='';--行为 SET @HisColoumnName =''; --列名 SET @Sql=''; SET @TableNameHistory=''; SET @altersql =''; --增加列 SET @sqlcolumn=''; -- 表结构增加列 SET @sqlcolumns =''; -- 新增字段 SET @sqlcolumnss=''; -- 别名 新增字段 SET @columnjson =''; -- json构造字段 SET @HisColoumnNameNO= ''; --开始捕获异常 BEGIN TRY --解析Json中的表名 SET @TableNameHistory=@TableName+'History'; --检查表是否存在 IF NOT EXISTS(select TOP 1 * from sys.objects where name = @TableName AND type='U') BEGIN SET @error ='没有'+@TableName RAISERROR(@error,16,1) END --解析表中列 SELECT COLUMN_NAME INTO #tablecoloumns FROM information_schema.COLUMNS WHERE TABLE_NAME=@TableNameHistory AND COLUMN_NAME <>'ID' --COLLATE Chinese_PRC_CI_AS IF NOT EXISTS(select TOP 1 * from sys.objects where name = @TableNameHistory AND type='U') BEGIN --SET @error=@error +' 没有'+@TableNameHistory --RAISERROR('@error',16,1) SET @Sql=' SELECT *,0 AS SourceID,CAST('''' AS VARCHAR(30)) AS Event INTO '+@TableNameHistory+' FROM '+@TableName+' WHERE 1=0 ' EXEC (@Sql); END IF (@ColoumnValue<>'') BEGIN -- 自动增加列是否需要实现 --begin --对比之后需要新增的字段 SET @altersql ='ALTER TABLE '+ @TableNameHistory+' ADD ' SELECT @sqlcolumn= STUFF(( SELECT ','+A.[Key]+CASE WHEN A.[Type]=1 THEN ' NVARCHAR(500)' WHEN A.[Type]=2 THEN ' INT' ELSE ' NVARCHAR(500)' END FROM (SELECT T.[Key],T.[Value],T.[Type] FROM OPENJSON(@ColoumnValue) ROOT CROSS APPLY OPENJSON(ROOT.[Value]) t WHERE ROOT.[Key]=0 AND t.[Key]<>'ID') A LEFT JOIN #tablecoloumns B ON A.[Key]=B.COLUMN_NAME COLLATE Chinese_PRC_CI_AS WHERE 1=1 AND ISNULL(b.COLUMN_NAME,'')='' FOR XML PATH('') ),1,1,'') IF(@sqlcolumn<>'') BEGIN SET @altersql+=@sqlcolumn EXEC (@altersql); END PRINT (@altersql); --新增列 SELECT @sqlcolumns= STUFF(( SELECT ','+A.[Key] FROM (SELECT T.[Key],T.Value,T.Type FROM OPENJSON(@ColoumnValue) ROOT CROSS APPLY OPENJSON(ROOT.Value) t WHERE ROOT.[Key]=0 AND t.[Key]<>'ID') A -- LEFT JOIN #tablecoloumns B ON A.[Key]=B.COLUMN_NAME COLLATE Chinese_PRC_CI_AS -- WHERE 1=1 AND ISNULL(b.COLUMN_NAME,'')='' FOR XML PATH('') ),1,0,'') --新增列 SELECT @sqlcolumnss= STUFF(( SELECT ',C.'+A.[Key] FROM (SELECT T.[Key],T.Value,T.Type FROM OPENJSON(@ColoumnValue) ROOT CROSS APPLY OPENJSON(ROOT.Value) t WHERE ROOT.[Key]=0 AND t.[Key]<>'ID') A -- LEFT JOIN #tablecoloumns B ON A.[Key]=B.COLUMN_NAME COLLATE Chinese_PRC_CI_AS -- WHERE 1=1 AND ISNULL(b.COLUMN_NAME,'')='' FOR XML PATH('') ),1,0,'') --循环插入新增字段的数据源 SELECT @columnjson= STUFF(( SELECT ','+A.[Key]+CASE WHEN A.[Type]=1 THEN ' NVARCHAR(500) ' WHEN A.[Type]=2 THEN ' INT' ELSE ' NVARCHAR(500)' END +' ''$.'+A.[Key]+'''' FROM (SELECT T.[Key],T.[Value],T.[Type] FROM OPENJSON(@ColoumnValue) ROOT CROSS APPLY OPENJSON(ROOT.[Value]) t WHERE ROOT.[Key]=0 ) A -- LEFT JOIN #tablecoloumns B ON A.[Key]=B.COLUMN_NAME COLLATE Chinese_PRC_CI_AS -- WHERE 1=1 AND ISNULL(b.COLUMN_NAME,'')='' FOR XML PATH('') ),1,1,'') END --找出表列名 SELECT @HisColoumnName= STUFF((SELECT ',A.'+COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME=@TableName AND COLUMN_NAME <>'ID' FOR XML PATH('')),1,1,'') SELECT @HisColoumnNameNO= STUFF((SELECT ','+COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME=@TableName AND COLUMN_NAME <>'ID' FOR XML PATH('')),1,1,'') --4 批量 5 单个对象 --遍历出列名 IF @ValueType=4 BEGIN --找出ID SELECT @ids=STUFF( (SELECT ','+TheValues.[value] FROM OPENJSON (@Json) AS root CROSS APPLY OPENJSON ( root.value) AS TheValues WHERE TheValues.[key]='ID' FOR XML PATH('')),1,1,'') --找出操作类型 SELECT @Action=TheValues.[value] FROM OPENJSON (@Json) AS root CROSS APPLY OPENJSON ( root.value) AS TheValues WHERE root.[Key]=0 AND TheValues.[key]='Action' IF @Action='Insert' BEGIN --直接left join 找出插入ID ,插入history表 SET @Sql= 'INSERT INTO ' +@TableNameHistory+' ('+@HisColoumnNameNO+',Event, SourceID'+' ) SELECT '+@HisColoumnName+','''+@Action+''' AS Event,A.ID '+' FROM '+@TableName +' AS A WHERE A.ID IN( ' SET @Sql =@Sql+'SELECT A.ID FROM '+@TableName +' A LEFT JOIN '+@TableNameHistory+' B ON A.ID =B.SourceID WHERE ISNULL(B.ID,0)=0 ' +' )' END ELSE BEGIN --SET @Sql ='INSERT INTO ' +@TableNameHistory+' ('+@HisColoumnName+@sqlcolumns+', Event, SourceID'+' ) SELECT '+@HisColoumnName+','''+@Action+''' AS Event,ID '+' FROM '+@TableName +' WHERE ID IN( '+@Ids +' )' IF @sqlcolumns<>'' BEGIN SET @Sql ='INSERT INTO ' +@TableNameHistory+' ('+@HisColoumnNameNO+@sqlcolumns+', Event, SourceID'+' ) SELECT '+@HisColoumnName+@sqlcolumnss+','''+@Action+''' AS Event,A.ID '+' FROM '+@TableName +' AS A LEFT JOIN ( SELECT * FROM OPENJSON('''+@ColoumnValue+''')WITH('+@columnjson+') ) C ON A.ID =C.ID '+' WHERE A.ID IN( '+@Ids +' )' END ELSE BEGIN SET @Sql ='INSERT INTO ' +@TableNameHistory+' ('+@HisColoumnNameNO+', Event, SourceID'+' ) SELECT '+@HisColoumnName+','''+@Action+''' AS Event,A.ID '+' FROM '+@TableName +' AS A WHERE ID IN( '+@Ids +' )' END END END ELSE IF @ValueType=5 BEGIN --找出ID SELECT @ids=root.[value] FROM OPENJSON (@Json) AS root WHERE root.[Key]='ID' --找出操作类型 SELECT @Action=root.[value] FROM OPENJSON (@Json) AS root WHERE root.[Key]='Action' IF @Action='Insert' BEGIN --直接left join 找出插入ID ,插入history表 SET @Sql= 'INSERT INTO ' +@TableNameHistory+' ('+@HisColoumnNameNO+', Event, SourceID'+' ) SELECT '+@HisColoumnName+','''+@Action+''' AS Event,A.ID '+' FROM '+@TableName +' AS A WHERE A.ID IN( ' SET @Sql =@Sql+'SELECT A.ID FROM '+@TableName +' A LEFT JOIN '+@TableNameHistory+' B ON A.ID =B.SourceID WHERE ISNULL(B.ID,0)=0 ' +' )' END ELSE BEGIN -- SET @Sql ='INSERT INTO ' +@TableNameHistory+' ('+@HisColoumnName+',Event,SourceID'+' ) SELECT '+@HisColoumnName+','''+@Action+''' AS Event,ID '+' FROM '+@TableName +' WHERE ID= '+@Ids IF @sqlcolumns<>'' BEGIN SET @Sql ='INSERT INTO ' +@TableNameHistory+' ('+@HisColoumnNameNO+@sqlcolumns+', Event, SourceID'+' ) SELECT '+@HisColoumnName+@sqlcolumnss+','''+@Action+''' AS Event,A.ID '+' FROM '+@TableName +' AS A LEFT JOIN ( SELECT * FROM OPENJSON('''+@ColoumnValue+''')WITH('+@columnjson+') ) C ON A.ID =C.ID '+' WHERE A.ID IN( '+@Ids +' )' END ELSE BEGIN SET @Sql ='INSERT INTO ' +@TableNameHistory+' ('+@HisColoumnNameNO+', Event, SourceID'+' ) SELECT '+@HisColoumnName+','''+@Action+''' AS Event,A.ID '+' FROM '+@TableName +' AS A WHERE ID IN( '+@Ids +' )' END END END --直接 DROP TABLE #tablecoloumns PRINT(@sql); BEGIN TRANSACTION EXEC (@sql); --结束捕获异常 END TRY --开始抛出异常 BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; DECLARE @ErrorMessage nvarchar(max) ,@ErrorNumber varchar(200),@ErrorSeverity varchar(200),@ErrorState varchar(200), @ErrorProcedure varchar(200),@ErrorLine varchar(200),@CreateDate datetime,@CreateBy varchar(20) SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorNumber = ERROR_NUMBER(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(), @ErrorProcedure = ERROR_PROCEDURE(), @ErrorLine = ERROR_LINE(), @CreateDate = getdate() --exec [dbo].[SYS_LogDBError] @ErrorMessage,@ErrorNumber,@ErrorSeverity,@ErrorState,@ErrorProcedure,@ErrorLine,@Json,@CreateDate,@userCode SET @JsonResult=(select @ErrorMessage as 'ErrorMessage' for json PATH) SELECT @JsonResult AS JsonResult END CATCH IF @@TRANCOUNT > 0 BEGIN COMMIT TRANSACTION; --提交事务 SET @JsonResult=(SELECT 'Success' as 'Result' for json PATH) SELECT @JsonResult AS JsonResult END END
以上是 对表的操作 新增历史记录。

浙公网安备 33010602011771号