SqlServer使用@@ROWCOUNT全局变量

我在一段while循环语句中设定了循环结束条件,执行语句时出现数据溢出错误,因此判断为循环结束条件失效,导致死循环至数据溢出,可是找了好久都没发现问题所在。

SQL表  [Structs]包含三个字段[ItemID]、[ParentID]、[LevelNum],表示层次ID、父层次ID、层次级数。

CREATE TABLE [dbo].[Structs](
	[ItemID] [VARCHAR](50) NULL,
	[ParentID] [VARCHAR](50) NULL,
	[LevelNum] [INT] NULL
)


表数据如下

SqlServer使用@@ROWCOUNT全局变量_第1张图片


表值函数GetChildren获取某个层次自身及的所有子层次信息。

ALTER FUNCTION [dbo].[GetChildren](@ID VARCHAR(50))
RETURNS @Children TABLE(ItemID VARCHAR(50),ParentID VARCHAR(50), LevelNum INT)
AS
BEGIN
	--根据ID获取项目当前等级
	DECLARE @LevelNum INT
	SELECT @LevelNum = LevelNum FROM Structs WHERE ItemID = @ID
	--将对应ID的记录插入新表
	INSERT INTO @Children SELECT * FROM Structs WHERE ItemID = @ID
	--连接原表,查询对应ID的所有子集
	WHILE @@ROWCOUNT <> 0
	BEGIN
		INSERT INTO @Children
		SELECT a.ItemID, a.ParentID, a.LevelNum
		FROM Structs a,@Children b
		WHERE a.ParentID = b.ItemID AND b.LevelNum = @LevelNum
		SET @LevelNum = @LevelNum + 1
	END
	RETURN 
END


经过仔细的思考,既然死循环了,就表示循环条件失效,即 @@ROWCOUNT <> 0恒为真了,@@ROWCOUNT 表示受影响的行数,一般用作判断DML语句即增删改操作是否成功,我令LevelNum每次循环+1,数据表中LevelNum最大只到4,按理说到加到5的时候INSERT INTO语句的WHERE条件就不成立,此时@@ROWCOUNT=0,循环就该结束了,然而最终@@ROWCOUNT<>0,为什么呢?于是我继续往下看,终于发现,我在循环结束之前添加结束条件,SET @LevelNum = @LevelNum + 1,难道这个SET语句
会导致@@ROWCOUNT <> 0 吗,为了验证这个猜测,我将语句做了修改,把循环结束条件放到了INSERT INTO语句之前。

WHILE @@ROWCOUNT <> 0
	BEGIN
		SET @LevelNum = @LevelNum + 1
		INSERT INTO @Children
		SELECT a.ItemID, a.ParentID, a.LevelNum
		FROM Structs a,@Children b
		WHERE a.ParentID = b.ItemID AND b.LevelNum = @LevelNum - 1
	END

接下来新建查询调用表值函数GetChildren

SELECT * FROM  dbo.GetChildren('5')

执行成功,没有发生溢出错误,确定是SET语句导致@@ROWCOUNT恒不为0,造成死循环。



你可能感兴趣的:(SQL)