谨记初始化变量

最近又被开发的小伙坑了,先看一个测试样例

--创建表并插入测试数据
CREATE TABLE ConfigForAll(KindID INT,TTable VARCHAR(64),FTable VARCHAR(64))
INSERT INTO ConfigForAll VALUES(1,'AdventureWorks2008R2.Sales.SalesOrderDetail','AdventureWorks2008R2.Sales.SalesOrderDetail')
,(2,'AdventureWorks2008R2.Sales.SalesOrderHeader','AdventureWorks2008R2.Sales.SalesOrderHeaderXXX')
,(3,'AdventureWorks2008R2.Sales.SalesOrderHeaderSalesReason','AdventureWorks2008R2.Sales.SalesOrderHeaderSalesReason')
GO
View Code

配置表中保存有需要统计行数的表名,TTable列全为正确表名,FTable列包含部分错误表名

--游标计算表中记录数(仅用于模拟,不考虑效率)
DECLARE @KindID INT
DECLARE @TTable VARCHAR(64)
DECLARE @FTable VARCHAR(64)
DECLARE loop_cursor CURSOR FOR
SELECT KindID,TTable,FTable FROM ConfigForAll ORDER BY KindID
OPEN loop_cursor
FETCH NEXT FROM loop_cursor INTO @KindID,@TTable,@FTable
WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @TCount INT
    DECLARE @FCount INT
    --SELECT @TCount=0,@FCount=0    --没有初始化变量
    DECLARE @sql NVARCHAR(MAX)
    DECLARE @sql_out NVARCHAR(MAX)
    --正确表名
    SET @sql='SELECT @TCount=count(*) FROM '+@TTable+' WITH(NOLOCK)'
    PRINT @sql
    SET @sql_out='@TCount INT output'
    EXEC sp_executesql @sql,@sql_out,@TCount OUTPUT
    --错误表名
    SET @sql='SELECT @FCount=count(*) FROM '+@FTable+' WITH(NOLOCK)'
    PRINT @sql
    SET @sql_out='@FCount INT output'
    EXEC sp_executesql @sql,@sql_out,@FCount OUTPUT
    --计算结果
    SELECT @KindID KindID,@TCount TCount,@FCount FCount
    
    FETCH NEXT FROM loop_cursor INTO @KindID,@TTable,@FTable
END
CLOSE loop_cursor
DEALLOCATE loop_cursor
View Code

使用游标逐行计算表中的记录数,执行消息和结果如下



1、执行过程有报错(对象名 'AdventureWorks2008R2.Sales.SalesOrderHeaderXXX' 无效。)
2、仅报错的行结果有误,后续行将继续执行。数据表不存在,变量值实际还是前一条记录的结果
真实环境有点类似,不同Game保存在不同的表,然后对各个Game统计多项指标。因此存在一张配置表,通过KindID区分Game,不同的指标需从不同的表格获取数据(配置多列)。
向开发反馈,配置表中的表在库中不存在;结果他说知道不存在,出错会终止?让他去看这两天的统计数据,然后他说去掉...
好小伙,发现他所说的去掉,就是把配置表中的那个单元置为''。依旧使用测试数据,"去掉"等效于

UPDATE ConfigForAll SET FTable='' WHERE KindID=2

然后使用开篇的游标语句,结果一样,执行消息稍有不同

这不是从一个坑跳入另一个坑!原本想简单粗暴点直接从配置表删除对应记录,那样其他指标与XXX表无关的统计都没了。最后采用NULL+String为NULL

UPDATE ConfigForAll SET FTable=NULL WHERE KindID=2

同时游标内声明变量后进行初始化操作!


真实环境的语句太惨不忍睹,各种嵌套,多行记录赋值给一个变量,部分还有with(index=index_name),一旦配置表中添加的数据表没有创建对应的索引,统计跟着死翘翘⊙0⊙

原文地址:https://www.cnblogs.com/Uest/p/6903755.html