0

我正在创建一个包含两个while循环的存储过程,下面提到的用于创建几个临时表,下一个循环将一些数据写入其中。

临时表名称是从静态表中检索的

问题:第一次迭代之后的下面的while循环并进入下一个循环(第二个)。我在这里做错了吗?

或者这就是while循环在SQL Server(Azure SQL MI)中一个过程中的工作方式?

以这种方式创建临时表也是一种好习惯吗?

declare @b varchar(100)
declare @bmax varchar(100)
declare @inpt_tbl_nm varchar(100)
declare @inpt_tbl_sql varchar(1000)
set @b = 1

select @bmax = max(RwId) from eds_int.abc

while @b < = @bmax
begin
    select @inpt_tbl_nm = otpt_tmp_tbl from eds_int.abc where Rwid=@b
    select @inpt_tbl_sql = 'create table ' + @inpt_tbl_nm + '(RowId INT IDENTITY(1,1), SchemaName sysname, TableName nvarchar(150), query nVARCHAR(4000), condition  nVARCHAR(4000))'

    exec (@inpt_tbl_sql)
    set @b = @b + 1
end

DECLARE @a INT
DECLARE @amax INT
DECLARE @max INT

SELECT @a = 1, @amax = MAX(RwId) from eds_int.abc

WHILE @a <= @amax
BEGIN
.
.
.
.
END

编辑:

declare @b int
declare @bmax int
declare @inpt_tbl_nm varchar(100)
declare @inpt_tbl_sql varchar(1000)
declare @test_query varchar(1000)

set @b = 1
select @bmax = 1
while @b < = @bmax
begin
print @b
select @inpt_tbl_nm = '#test_delete'
select @inpt_tbl_sql = 'create table ' + @inpt_tbl_nm + '(RowId INT IDENTITY(1,1), SchemaName sysname, TableName nvarchar(150), query nVARCHAR(4000), condition  nVARCHAR(4000))'
exec (@inpt_tbl_sql)
print @inpt_tbl_sql
select @test_query = 'select * from ' + @inpt_tbl_nm
exec (@test_query)
set @b = @b + 1
end

错误:消息 208,级别 16,状态 0,第 1 行无效的对象名称“#test_delete”。

4

1 回答 1

3

我对WHILE静止的观点来自评论;并且该过程也很可能存在缺陷。你所拥有的意义不大。

您有 2 个变量@b@bmax它们都是varchar(100)s。我不知道@bmax设置的值是什么,但让我们假设它是'10' (not 10)并且您将值设置@b'1' (not 1)此外,您使用 a 的事实varchar(100)意味着您需要将“数字”存储到(10*10^99)-1. 这比显然被称为“Googol”的东西少了1个。

然后进入第一个循环,因此 RDBMS 检查'1'小于'10' 1小于10)。就是这样WHILE输入的。并执行第一次迭代。

在该迭代结束时,您拥有set @b = @b + 1,它转换为以下内容(使用数据类型优先级):

@b + 1 = '1' + 1 = 1 + 1 = 2 ∴ @b = '2'

然后你WHILE重新开始,检查'2'小于'10'小于)210这失败了,因为大于'2'所以你退出了。'10'WHILE

TL;DR:数据类型很重要。字符串不是数字,它们的行为也不像数字。

于 2019-12-26T16:20:48.460 回答