凭借我有限的SQL知识,我无法弄清楚这一点。以下是什么问题:
DECLARE @Id int
DECLARE @Name varchar(40)
WHILE EXISTS
(
SELECT TOP 1 @Name = Name, @Id=ID FROM MyTable c WHERE <CONDITION>
)
BEGIN
SOME MORE SQL using @Id and @Name
END
我在@Name = Name
要为问题添加更多上下文,我有两个名为Category (ID, Name, ParentID)
和Account(ID, Name, CategoryID)
的表。
Categories
有3个等级。
这是使用递归关系(ParentID
&gt; CategoryID
)实现的。要解决的问题是,如果有任何属于X类({2级)的Accounts
,我们必须
这是我写的原始剧本:
DECLARE @Id int
DECLARE @Name varchar(40)
WHILE EXISTS(
SELECT TOP 1 @Name=Name, @Id=CategoryID FROM Category c WHERE
ParentID = (SELECT TOP 1 CategoryID FROM Category WHERE Name = 'Root') AND
(SELECT COUNT(*) FROM Account WHERE CategoryID = c.CategoryID) > 0
)
BEGIN
INSERT INTO Category(Name, ParentID) VALUES(@Name, @Id)
UPDATE Account SET CategoryID = @@IDENTITY WHERE CategoryID = @Id
END
答案 0 :(得分:2)
您可以使用CURSOR
循环:
CREATE TABLE MyTable(ID INT, Name VARCHAR(100));
INSERT INTO Mytable(ID, Name) VALUES (1,10),(2,20);
DECLARE @Id int;
DECLARE @Name varchar(40);
DECLARE cur CURSOR FAST_FORWARD FOR SELECT Name,ID FROM MyTable c WHERE 1=1;
OPEN cur;
FETCH NEXT FROM cur INTO @Id, @Name;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Id,@Name;
FETCH NEXT FROM cur INTO @Id, @Name;
END;
CLOSE cur;
DEALLOCATE cur;
的 LiveDemo
强>
请注意,没有明确TOP 1
的{{1}}可能会在执行之间产生不同的结果。
EXISTS子查询
请注意,ORDER BY
不是子查询,而是赋值。
SELECT @ID = id, @Name = Name
的 LiveDemo 2
强>
答案 1 :(得分:1)
没有必要使用While
,你可以使用if条件代替while
这样 - “
DECLARE @Id int
DECLARE @Name varchar(40)
SELECT TOP 1 @Name = Name, @Id=ID FROM MyTable c WHERE <CONDITION>
-- Now Check for @Name and @ID
IF ISNULL(@Name, '') <> '' AND ISNULL(@Id, 0) <> 0
BEGIN
SOME MORE SQL using @Id and @Name
END
<强> EDITED 强>
IF EXISTS(SELECT 1 FROM Category c
WHERE ParentID = (SELECT TOP 1 CategoryID FROM Category WHERE Name = 'Root')
AND (SELECT COUNT(*) FROM Account WHERE CategoryID = c.CategoryID) > 0
)
BEGIN
SELECT TOP 1 @Name=Name, @Id=CategoryID FROM Category c
WHERE ParentID = (SELECT TOP 1 CategoryID FROM Category WHERE Name = 'Root')
AND (SELECT COUNT(*) FROM Account WHERE CategoryID = c.CategoryID) > 0
INSERT INTO Category(Name, ParentID)
VALUES(@Name, @Id)
SET @CategoryID = SCOPE_IDENTITY()
UPDATE Account SET CategoryID = @CategoryID WHERE CategoryID = @Id
END
答案 2 :(得分:1)
SELECT @local_variable (Transact-SQL)
不能使用包含变量赋值的SELECT语句 也执行典型的结果集检索操作。
在这里你使用EXISTS来检索数据,所以我猜你不能在子查询中使用赋值。
尝试使用BREAK实现等效的WHILE TRUE循环。
{{1}}
答案 3 :(得分:0)
将此用于检查记录存在
WHILE EXISTS
(
SELECT TOP 1 * FROM MyTable c WHERE <CONDITION>
)
BEGIN
SELECT TOP 1 @Name = Name, @Id=ID FROM MyTable c WHERE <CONDITION>
-- and do here what you want
END