为什么在for循环中,`i` 总是被看作是1?

我编写了这个简单的脚本来更新 MySQL 中的一个表格。为此,我创建了一个 for 循环并尝试了以下内容([codepad 链接] (http://codepad.org/sXKJan4O)):

sUpdate = [[UPDATE `latest`
SET `date` = '%s'
WHERE `date` = '%s'
AND `fid` > 50000]]

for i = 1, 12 do
  print( i )
  sOldDate = "2009-"..tostring(i).."-10"
  sNewDate = "2010-09-"..tostring(i)
  sUpdate = string.format( sUpdate, sNewDate, sOldDate )
  print( sUpdate )
end

输出如下:

1
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
2
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
3
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
4
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
5
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
6
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
7
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
8
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
9
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
10
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
11
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000
12
UPDATE `latest`
SET `date` = '2010-09-1'
WHERE `date` = '2009-1-10'
AND `fid` > 50000

正如你所看到的 print(i) 打印得很好,但 sOldDatesNewDate 都将 i 视为 1。然后我将 sOldDatesNewDate 更改为以下内容:

sOldDate = string.format("2009-%d-10", i)
sNewDate = string.format("2010-09-%d", i)

我仍然得到了两个日期的输出:2009-1-10 和 _2010-09-1_,如此 [这里] (http://codepad.org/c8KkzORY) 所示。

这个循环可能有什么问题。我已经在这样的循环上工作了很长时间,直到今天才出问题。

我认为这只是我的一些愚蠢的错误,我无法识别。任何帮助都将不胜感激。

点赞
用户295262
用户295262

是的,问题在于每次都在覆盖 sUpdate

第一次,您会覆盖字符串占位符 %s,之后,字符串将不再改变。

尝试将内部 sUpdate 重命名。而且我认为您想要所有变量都作为 local

local sUpdate = [[UPDATE `latest`
SET `date` = '%s'
WHERE `date` = '%s'
AND `fid` > 50000]]

for i = 1, 12 do
  print( i )
  local sOldDate = "2009-"..tostring(i).."-10"
  local sNewDate = "2010-09-"..tostring(i)
  local sUpdate = string.format( sUpdate, sNewDate, sOldDate )
  print( sUpdate )
end

编辑: 如上所示,我保留了您的变量名,但内部 sUpdate 不会覆盖外部的 sUpdate,因为它被声明为 local。在 Lua 中,默认情况下所有变量都是全局的,因此最好确保使用 local 声明局部变量。我建议使用不同的变量名,例如:

local sUpdateTemplate = [[UPDATE `latest`
SET `date` = '%s'
WHERE `date` = '%s'
AND `fid` > 50000]]

for i = 1, 12 do
  print( i )
  local sOldDate = "2009-"..tostring(i).."-10"
  local sNewDate = "2010-09-"..tostring(i)
  local sUpdate = string.format( sUpdateTemplate, sNewDate, sOldDate )
  print( sUpdate )
end
2012-07-19 08:39:57
用户1516484
用户1516484

如上所述,你需要在循环中重新命名 sUpdate,以避免覆盖外部的变量并破坏 string.format()。然后可以在 string.format() 中使用 %02d,将数字至少补零到两位长度:

local sUpdate = [[UPDATE `latest`
SET `date` = '%s'
WHERE `date` = '%s'
AND `fid` > 50000]]

for i = 1, 12 do
  print( i )
  local sOldDate = string.format("2010-%02d-10", i)
  local sNewDate = string.format("2010-09-%02d", i)
  local update = string.format( sUpdate, sNewDate, sOldDate )
  print( update )
end
2012-07-19 08:49:13