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
)


表數據如下



表值函數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,造成死循環。



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