简体   繁体   English

SELECT while 循环中的语句不工作

[英]SELECT statement in while loop isn't working

I have created the following Select statement which is working fine:我创建了以下运行良好的 Select 语句:

SELECT @Block = [Blok], @Year = [Aar] 
FROM [PT99991_Result].[dbo].[Testheader] 
WHERE N = @TestHeaderID

The problem is that this Select statement is used in a While loop where the database can change to another one during the loop.问题是这个Select语句用在While循环中,其中数据库可以在循环期间更改为另一个。 I have tried to modify the statement to the following but it's not working.我试图将声明修改为以下内容,但它不起作用。 I have also tried to use EXEC which takes care of my problem but then I'm facing a problem with the local variables @Block and @Year instead.我也尝试过使用EXEC来解决我的问题,但后来我遇到了局部变量@Block@Year的问题。

SET @DataBase = 'PT99991_RESULT' --This is only for test!

SELECT @Block = [Blok], @Year = [Aar] 
FROM '[' + @DataBase + '].[dbo].[Testheader]' 
WHERE N = @TestHeaderID

I'm not sure what I'm doing wrong?我不确定我做错了什么?

First, generate a T-SQL template like this:首先,生成一个像这样的 T-SQL 模板:

DECLARE @DynamicTSQLStatement NVARCHAR(MAX) = N'SELECT @Block = [Blok], @Year = [Aar] 
                                                FROM [@DataBase].[dbo].[Testheader] 
                                                WHERE N = @TestHeaderID';

Then, let's say that the variale @Datbase holds your current database name.然后,假设变量@Datbase包含您当前的数据库名称。 If it is not extracted from sys.database you can perform additional validation to ensure nobody is doing something wrong.如果它不是从sys.database中提取的,您可以执行额外的验证以确保没有人做错什么。

IF NOT EXISTS(SELEFT 1 FROM sys.database WHERE [name] = @Datbase
BEGIN
    ....
END;

After the validation, you just replace the database name in the template:验证后,您只需替换模板中的数据库名称:

SET @DynamicTSQLStatement = REPLACE(@DynamicTSQLStatement, '@Database', @Database);

Then, execute the code passing the parameters:然后,执行传递参数的代码:

EXEC sp_executesql @DynamicTSQLStatement
                  ,N'@TestHeaderID INT'
                  ,N'@Block INT OUTPUT'
                  ,N'@Year INT OUTPUT'
                  ,@TestHeaderID
                  ,@Block OUTPUT
                  ,@Year OUTPUT;

of course on every loop iteration, reset the template.当然,在每次循环迭代中,重置模板。

Instead of while loop, You can go for undocumented stored procedure: ms_foreachdb and execute against the databases and finally apply filter for the specific database.代替 while 循环,您可以 go 用于未记录的存储过程:ms_foreachdb 并针对数据库执行,最后为特定数据库应用过滤器。

Caveat : Don't use this in production code, because, it uses undocumented stored procedure.警告:不要在生产代码中使用它,因为它使用未记录的存储过程。

CREATE TABLE #test(dbname sysname, blok int, aar int)
DECLARE @db_list NVARCHAR(max) = 'DB1,DB2'

EXECUTE master.sys.sp_MSforeachdb 'USE [?]; declare @blok int, @aar int; INSERT INTO #test SELECT db_name(), blok, aar from [dbo].[Testheader] WHERE N = TestHeaderId;'

SELECT * FROM #test where dbname in 
(
SELECT value FROM string_split(@db_list,',')
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM