我正在尝试用一些虚拟数据填充我的数据库表,并为此编写了一个循环。我正在使用 DBeaver 连接到我的 SQL Server 数据库,并针对它运行代码。
DECLARE @counter INT = 1;
WHILE @counter <= 1000
BEGIN
INSERT INTO dbo.Articles
(ArticleCode, ArticleName)
VALUES
('ARTCODE' + CAST(@counter AS VARCHAR), 'Name' + CAST(@counter AS VARCHAR))
;
SET @counter = @counter + 1;
END;
由于某种原因,我在第 3 行(在 WHILE 循环上)收到错误。
SQL 错误 [137] [S0002]:必须声明标量变量“@counter”
我做错了什么?
问题出在 DBeaver 上,而不是你的 SQL 上。DBeaver 与 T-SQL 一起使用时,将分号 (
;
)视为批分隔符而不是语句终止符,尽管事实上它在设置中被定义为“语句终止符”。由于这种不良行为(错误),这意味着即使像下面这样的简单批处理也会失败:
在 SSMS 中,就像编写以下内容:
(
GO
故意设置 2 秒,因为 DBeaver还将空行视为语句批分隔符。)相反,您需要在编辑器 > SQL 编辑器 > SQL 处理中更改首选项。我用来获得正常 T-SQL 行为的方法是:
GO
这意味着上面的脚本有效,并且第二批中出现了未定义的错误
@test
,并且屏幕上的“智能感知”似乎也给出了正确的行为。截屏包含示例 DDL 和 DML 将使这个问题更容易解决。考虑:
DECLARE @Table TABLE (Column1 INT, Column2 DATE, ...); INSERT INTO @Table (Column1, Column2, ...) VALUES (1, '2024-01-01', ...), (2, '2024-02-01', ...);
此外,正如评论中提到的,使用没有长度的 [N]Varchar 是不好的做法。
我无法重现您的问题,但请考虑:
这会生成一个包含 1000 行的公用表表达式,然后使用字符串连接从中进行选择以插入到虚拟表中。
SQL 不能很好地处理循环,因此最好尽可能避免使用循环。经验法则是,如果您发现自己在使用光标,那么您可能没有以最佳方式进行操作。
您可以只从系统表中进行选择,例如
syscomments
并使用它rownumber()
来大大简化并执行单个插入。我相信concat
也是在 2012 年推出的。