【问题标题】:T-sql Concatenate variables for use in an Insert Into while loopT-sql 连接变量以在 Insert Into while 循环中使用
【发布时间】:2020-04-28 21:47:51
【问题描述】:

我正在尝试创建一个 SQL 语句,以便在创建一系列相同且仅在某些地方增加的 CTE 或临时表时节省时间。我可以用 VBA 做到这一点,但我不知道这是否可以用 SQL 实现

我正在尝试运行以下代码

DECLARE @N as INT
DECLARE @POINTS as TABLE(ID int Not Null,n varchar(3) Not Null)
DECLARE @TABLENAME varchar(6)

Set @INC = 1
Set @N = 5

--WHILE @INC <= @N
--BEGIN

Declare @N1 INT
Declare @N2 INT
Declare @N3 INT
Declare @N4 INT
Declare @N5 INT
SET @N1=25
SET @N2=50
SET @N3=100
SET @N4=250
SET @N5=500
--END

WHILE @INC <= @N
    BEGIN
        INSERT INTO @POINTS(ID, n) 
        VALUES (@INC, CONCAT('@N',@INC))
        SET @INC = @INC + 1
    END

Select * from @POINTS

这些是代码运行后的结果:

ID  n
1   @N1
2   @N2
3   @N3
4   @N4
5   @N5

是否可以将我为每个 @Nx 变量设置的值插入到 n 列而不是连接的字符值?如果是这样,怎么做?我找不到任何尝试这样做的人的结果。

我可以通过使用外部表来解决这个问题,但我想知道这是否可能。

【问题讨论】:

  • 这整件事闻起来像是个错误。 SQL 不是一种编程语言,在这个世界上使用循环几乎从来都不是正确的解决方案。我不确定为什么您想要“一系列相同且仅在某些地方增加的 CTE 或临时表”,但我几乎可以保证这是解决问题的错误方法您可能面临的问题。这在我看来很像XYPropblem
  • 我正在考虑使用循环,因为我想在需要进行更改时减少返工时间。我已经把它写成一个有效的传统 SQL 语句。问题是,当我想进行更改时,我必须触及五个不同的表定义,除了命名之外,它们在各方面都是相同的。我实际上是在使用 NotePad++ 并使用替换工具来更改代码,然后复制/粘贴
  • “我必须接触五个不同的表定义,除了命名之外,它们在各方面都相同。”这就是糟糕的数据库设计的标志(除了临时或简单的 Id-to-name 转换表)。如果您有多个表来描述单个业务实体 - 这是您的数据库设计中的一个问题。
  • 数据库设计没有任何问题,我正在从现有数据库中提取不同数量的测试值,以便查看能力统计信息随时间的变化情况。唯一改变的是每次迭代的 N 计数。

标签: tsql variables while-loop concatenation


【解决方案1】:

如果你只有少量的 values 值,你不妨编写一个插入语句,将所有 5 行插入到表中:

INSERT INTO @POINTS(ID, n) VALUES 
(1, '5'), 
(2, '25'), 
(3, '50'),
(4, '100'),
(5, '250'),
(6, '500');

如果你有太多的值要这样写,你可以使用 cte 生成一个内联的计数表,并使用该计数表中的insert...select

DECLARE @Points as TABLE
(
    ID int Not Null,
    n varchar(3) Not Null
);

WITH E10(N) AS
(
    SELECT 1 
    FROM (VALUES(0), (1), (2), (3), (4), (5), (6), (7), (8), (9))V(N)
), Tally(N) AS
(
    -- Since all the numbers are multiples of 5, 
    -- there's no point of populating the tally
    -- with numbers that aren't multiples of 5....
    SELECT ROW_NUMBER() OVER(ORDER BY @@SPID) * 5
    FROM E10 As Ten
    CROSS JOIN E10 As Hundred
    --Need more? Add more cross joins 
    -- each will multiply the number of rows by 10:
    --CROSS JOIN E10 As Thousand
    --CROSS JOIN E10 As [Ten Thousand] -- and so on    
)

INSERT INTO @Points(ID, n) 
SELECT ROW_NUMBER() OVER(ORDER BY N), CAST(N as varchar(3))
FROM Tally
WHERE N IN(5, 25, 50, 100, 250, 500);

SELECT *
FROM @Points;

结果:

ID  n
1   5
2   25
3   50
4   100
5   250
6   500

当然,如果你已经有一个计数表,你就不需要 cte...

【讨论】:

    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 2012-02-26
    • 2020-06-30
    • 1970-01-01
    • 2012-10-05
    • 2013-03-26
    • 2011-04-19
    • 1970-01-01
    相关资源
    最近更新 更多