我正在寻找任何有效的方法来解决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中的for i in L = ['A', 'B',..., 'N']
部分。
谢谢!
答案 0 :(得分:3)
您的问题还不清楚...
SQL-Server是基于 set 的工具。每当您觉得需要遍历集合的循环/迭代时,您都可能从错误的角度来解决问题。
第一个问题:如何提供字符列表?是表格,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;
这会将每个单独的char
插入表@tbl
中。当然,您也可以在任何其他上下文(例如WHERE
条件)中使用它。
无论如何,无论您的列表包含1、10还是一千个元素,该语句都不必更改。
如果您需要更多帮助,您确实应该提供更多背景信息。最好的方法是像上面一样创建一个独立方案。您可能想了解有关XY问题的信息...
答案 1 :(得分:0)
这解决了我的问题,我想这离实现它的最佳方式还很远。
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