使用While循环进行SQL Server更新

使用While循环进行SQL Server更新,sql,sql-server-2005,loops,Sql,Sql Server 2005,Loops,我正在努力提高SQL编程的效率。 我正在尝试运行一个循环,以对只更改数字后缀的字段名重复update命令 例如,不是为每次更新写出x_1,y_1,而是x_2,y_2: DECLARE @a INT DECLARE @b VARCHAR SET @a = 1 WHILE @a < 30 set @b = @a BEGIN UPDATE source set h = h + "x_"+@b where "y_"+@b = 'Sold' SE

我正在努力提高SQL编程的效率。 我正在尝试运行一个循环,以对只更改数字后缀的字段名重复update命令

例如,不是为每次更新写出
x_1,y_1
,而是
x_2,y_2

DECLARE @a INT 
DECLARE @b VARCHAR 

SET @a = 1
WHILE @a < 30
set @b = @a
  BEGIN
       UPDATE source set h = h + "x_"+@b
           where "y_"+@b = 'Sold'
    SET @a = @a + 1
  END
DECLARE@a INT
声明@b VARCHAR
设置@a=1
而@a<30
设置@b=@a
开始
更新源集h=h+“x_904;”+@b
其中“y_u3;”+@b=‘已售出’
设置@a=@a+1
结束
如果我能澄清,请告诉我。我正在使用SQLServer2005

谢谢你的指导


我试图应用亚当斯的解决方案,需要了解在以下情况下N'的正确用法:

exec sp_executesql update source_temp set pmt_90_day = pmt_90_day + convert(money,'trans_total_'+@b'')
    where convert(datetime,'effective_date_'+@b) <= dateadd(day,90,ORSA_CHARGE_OFF_DATE)
    and DRC_FLAG_'+@b = 'C'
exec sp_executesql update source_temp set pmt_90_day=pmt_90_day+convert(货币,'trans_total_'+@b'')

其中convert(datetime,'effective_date_'+@b)实际上不起作用,因为列名不能用引号括起来。实际上,您要做的是让SQL比较两个始终不同的字符串,这意味着您永远不会执行更新

如果你必须这样做的话,你必须要有像

DECLARE @a INT 
DECLARE @b VARCHAR 
SET @a = 1

WHILE @a < 30
BEGIN
set @b = @a  
exec sp_executesql N'UPDATE source set h = h + 'x_'+@b + N'
           where y_'+@b + N' = ''Sold'''   

SET @a = @a + 1
END
DECLARE@a INT
声明@b VARCHAR
设置@a=1
而@a<30
开始
设置@b=@a
exec sp_executesql N'更新源集h=h++'x_'+@b+N'
其中y'+@b+N'=''出售''
设置@a=@a+1
结束

然而,总的来说,我不鼓励这种做法。我不喜欢在另一个SQL语句中为任何类型的生产代码生成动态SQL。对于完成一次性开发任务非常有用,但我不喜欢它用于可能由用户执行的代码。

这实际上不起作用,因为您不能将列名括在引号中。实际上,您要做的是让SQL比较两个始终不同的字符串,这意味着您永远不会执行更新

如果你必须这样做的话,你必须要有像

DECLARE @a INT 
DECLARE @b VARCHAR 
SET @a = 1

WHILE @a < 30
BEGIN
set @b = @a  
exec sp_executesql N'UPDATE source set h = h + 'x_'+@b + N'
           where y_'+@b + N' = ''Sold'''   

SET @a = @a + 1
END
DECLARE@a INT
声明@b VARCHAR
设置@a=1
而@a<30
开始
设置@b=@a
exec sp_executesql N'更新源集h=h++'x_'+@b+N'
其中y'+@b+N'=''出售''
设置@a=@a+1
结束

然而,总的来说,我不鼓励这种做法。我不喜欢在另一个SQL语句中为任何类型的生产代码生成动态SQL。对于完成一次性开发任务非常有用,但我不喜欢它用于可以由用户执行的代码。

Adam对问题本身进行了很多探讨,但我要提到的是潜在的问题,这只是一个症状。您的数据模型几乎肯定是糟糕的。如果您计划进行大量(任何)SQL开发,您应该阅读一些关于数据建模的介绍性书籍。规范化的首要规则之一是实体中不应包含重复组。例如,您不应该有名为“phone_1”、“phone_2”等的列

这里有一个更好的方法来模拟这种情况:

CREATE TABLE Contacts (
     contact_id INT NOT NULL,
     contact_name VARCHAR(20) NOT NULL,
     contact_description VARCHAR(500) NULL,
     CONSTRAINT PK_Contacts PRIMARY KEY CLUSTERED (contact_id)
)

CREATE TABLE Contact_Phones (
     contact_id INT NOT NULL,
     phone_type VARCHAR(10) NOT NULL,
     phone_number VARCHAR(20) NOT NULL,
     CONSTRAINT PK_Contact_Phones PRIMARY KEY CLUSTERED (contact_id, phone_type),
     CONSTRAINT CK_Contact_Phones_phone_type CHECK (phone_type IN ('HOME', 'FAX', 'MOBILE'))
)

现在,您可以将它们作为一个集合来处理,并通过业务逻辑获取所需的电话号码,而不是尝试将字符串连接起来处理不同的列。(很抱歉,我没有使用你的例子,但它似乎有点太笼统和难以理解)。

亚当在问题本身上打了很多主意,但我要提到的是潜在的问题,这只是一个症状。您的数据模型几乎肯定是糟糕的。如果您计划进行大量(任何)SQL开发,您应该阅读一些关于数据建模的介绍性书籍。规范化的首要规则之一是实体中不应包含重复组。例如,您不应该有名为“phone_1”、“phone_2”等的列

这里有一个更好的方法来模拟这种情况:

CREATE TABLE Contacts (
     contact_id INT NOT NULL,
     contact_name VARCHAR(20) NOT NULL,
     contact_description VARCHAR(500) NULL,
     CONSTRAINT PK_Contacts PRIMARY KEY CLUSTERED (contact_id)
)

CREATE TABLE Contact_Phones (
     contact_id INT NOT NULL,
     phone_type VARCHAR(10) NOT NULL,
     phone_number VARCHAR(20) NOT NULL,
     CONSTRAINT PK_Contact_Phones PRIMARY KEY CLUSTERED (contact_id, phone_type),
     CONSTRAINT CK_Contact_Phones_phone_type CHECK (phone_type IN ('HOME', 'FAX', 'MOBILE'))
)
现在,您可以将它们作为一个集合来处理,并通过业务逻辑获取所需的电话号码,而不是尝试将字符串连接起来处理不同的列。(很抱歉,我没有使用您的示例,但它似乎有点过于笼统,难以理解)。

而@count
而@count<@countOfSession
开始
如果@day='星期六'或@day='星期二'
开始
如果@day='Saturday'
开始
选择@date
设置@day='星期二'
设置@count=@count+1
设置@date=@date+3
结束
如果@day='星期二'
开始
选择@date
设置@day='Saturday'
设置@count=@count+1
设置@date=@date+4
结束
结束
结束

Adam,如果您能帮助我修改版本,我将不胜感激。@homer:N'创建一个nvarchar,而不是varchar。它是一个字符串引用标识符。例如,N'This is my string'是一个nvarchar,而'This is my string'是一个varchar。我使用N'是因为sp_executesql需要一个nvarchar。亚当,如果你能帮我修改一下,我将不胜感激。@homer:N'创建一个nvarchar,而不是varchar。它是一个字符串引用标识符。例如,N'This is my string'是一个nvarchar,而'This is my string'是一个varchar。我使用N'是因为sp_executesql接受一个nvarchar。