迭代T-SQL中的字符列表

迭代T-SQL中的字符列表,sql,loops,tsql,for-loop,Sql,Loops,Tsql,For Loop,我正在寻找任何有效的方法来解决T-SQL中的以下问题: for i in L = ['A', 'B',..., 'N'] INSERT INTO MyTable1 (SomeCol1, SomeCol2) SELECT SomeCol1, SomeCol2 FROM SomeTable1 WHERE <conditions> UPDATE MyTable1 SET MyCol1 = i WHERE MyCol1 = 'the default value of MyCol1' 考虑

我正在寻找任何有效的方法来解决T-SQL中的以下问题:

for i in L = ['A', 'B',..., 'N'] 
INSERT INTO MyTable1 (SomeCol1, SomeCol2)
SELECT SomeCol1, SomeCol2 FROM SomeTable1 WHERE <conditions>
UPDATE MyTable1 SET MyCol1 = i WHERE MyCol1 = 'the default value of MyCol1'
考虑到我的字符列表L很长,我不想对每个元素单独执行一次。因此,如果有比使用循环更好的解决方案,我对它感兴趣,只要它解决了问题。请注意,我并没有试图使用上面的正确语法-我还想知道如何处理T-SQL中L=['A'、'B'、…、'N']中的I部分


谢谢

你的问题很不清楚

SQL Server是一种基于集合的工具。每当你觉得需要循环/迭代一个集合时,你可能是从错误的角度来处理你的问题

第一个问题:您如何提供角色列表?它是表、JSON、XML还是CSV字符串

无论如何,你的目标必须是把它作为一个集合

只是为了说明原则:如果您提供您的字符,例如作为一个简单的列表,您可以使用递归CTE

DECLARE @L VARCHAR(100)='ACFHJTZJ'; --add as many as you need

WITH recCTE AS
(
    SELECT 1 AS Pos,SUBSTRING(@L,1,1) AS OneChar
    UNION ALL
    SELECT r.Pos+1, SUBSTRING(@L,r.Pos+1,1)
    FROM recCTE r
    WHERE r.Pos<LEN(@L)
)
SELECT /*add DISTINCT if you want to surpress repeating characters*/ 
       Pos,OneChar 
FROM recCTE;
这将以派生表的形式返回所有字母

您可以使用这样的集合,但是您可以在基于集合的语句中创建它,如下所示:

DECLARE @L VARCHAR(100)='ACFHJTZJ'; --add as many as you need
DECLARE @tbl TABLE(SomeColumn CHAR(1));

WITH recCTE AS
(
    SELECT 1 AS Pos,SUBSTRING(@L,1,1) AS OneChar
    UNION ALL
    SELECT r.Pos+1, SUBSTRING(@L,r.Pos+1,1)
    FROM recCTE r
    WHERE r.Pos<LEN(@L)
)
INSERT INTO @tbl(SomeColumn)
SELECT DISTINCT OneChar 
FROM recCTE;

SELECT * FROM @tbl;
这将把每个单独的字符插入到表@tbl中。当然,您也可以在任何其他上下文中使用它,比如WHERE条件

在任何情况下,此语句都不必更改您的列表是否包含1、10或1000个元素


如果你需要更多的帮助,你真的应该提供更多的背景信息。最好的方法是创建一个独立的场景,就像我上面所做的那样。你可能想了解XY问题…

这解决了我的问题,我想这远不是最好的解决方法

CREATE TABLE MyTable2 (MyCol2 VARCHAR(5))
INSERT INTO MyTable2 (MyCol2) VALUES ('A')
INSERT INTO MyTable2 (MyCol2) VALUES ('B')
.
.
.
INSERT INTO MyTable2 (MyCol2) VALUES ('N')
ALTER TABLE MyTable2 ADD ID INT IDENTITY

WHILE (SELECT COUNT(*) FROM MyTable2) > 0
BEGIN
  INSERT INTO MyTable1 (SomeCol1, SomeCol2)
  SELECT SomeCol1, SomeCol2 FROM SomeTable1 WHERE <conditions>
  UPDATE MyTable1 
  SET MyCol1 = (SELECT MyCol2 FROM MyTable2 HAVING ID = MIN(ID)) 
  WHERE MyCol1 = 'the default value of MyCol1'
  DELETE FROM MyTable2 WHERE MyCol2 = (SELECT MyCol2 FROM MyTable2 HAVING ID = MIN(ID))
END

你能提供一些示例数据和预期结果吗?如果你没有设置where条件,那么你的更新MyTable SET mycl=i没有意义,因为mycl将设置为L列表中的最后一个字符,我可以,但看不出这会使事情变得更简单。这个问题会变得很长,读起来不好。我认为最重要的是我想循环一个字符列表或循环以外的任何其他解决方案,其中代码量不会随着列表的长度而增加。集合后有一个where条件我忽略了,但我可以用它来更新问题。@CHRD SQL是一种基于集合的语言。很少需要使用循环。这当然不是极少数情况之一。您可以基于联接更新表,例如更新我的表集。。。从MyTable内部连接MyCharacterSource。。。事实上,这个问题很不清楚。这些角色来自哪里?SQL没有数组。它们来自TVP、视图、功能吗?谢谢!比其他一些痛苦的评论有用得多:以表格形式提供字符列表是很好的。没有必要像我回答的那样耍花招。但是,用你的话来说:更有用的是一些示例输入和预期输出。我可以肯定地告诉你!,你的方法——同样是你的话——远远不是最佳的方式。。。但如果没有更好的理解,这纯粹是猜测……我明白你的意思。我想很多人都想以这样的心态来看待这些问题:这个问题的最佳解决方案是什么?。在这种情况下,任何背景信息都有帮助。但这种方法最终可能会导致复杂的讨论,这就是为什么我试图界定问题,以便更简单地解决问题——在这种情况下,试图回答问题的人需要相信问题的表述,而不是引用XY问题。我提供的答案不需要比问题中已经说明的更多的信息,目前对我来说已经足够了,虽然不是最优的。好吧,我也明白你的观点,但我认为这是不正确的。想象一下另一边的专家。您的解决方案离T-SQL太远了,专家永远不会给出这样的答案。询问一位伟大的厨师如何用便宜的方便食品制作比萨饼。你认为你会得到答案吗?我很确定,不会有关于最佳解决方案的复杂讨论。在最糟糕的情况下,你会用不同的方法得到几个答案。这样你就可以挑一个你最喜欢的…谢谢你的意见。在任何情况下,无论我们是否同意对方,我真的很感谢你花时间评论和张贴答案。干杯