【问题标题】:How do I fetch multiple columns for use in a cursor loop?如何获取多个列以在游标循环中使用?
【发布时间】:2012-06-17 14:37:42
【问题描述】:

当我尝试在游标循环中运行以下 SQL sn-p 时,

set @cmd = N'exec sp_rename ' + @test + N',' +
           RIGHT(@test,LEN(@test)-3) + '_Pct' + N',''COLUMN'''

我收到以下消息,

消息 15248,级别 11,状态 1,过程 sp_rename,第 213 行
参数@objname 不明确或声明的@objtype (COLUMN) 错误。

出了什么问题,我该如何解决?我尝试将列名括在括号[] 和双引号"" 中,就像一些搜索结果所建议的那样。

编辑 1 -

这是整个脚本。如何将表名传递给 rename sp ?我不知道该怎么做,因为列名位于许多表之一中。

BEGIN TRANSACTION

declare @cnt int
declare @test nvarchar(128)
declare @cmd nvarchar(500) 
declare Tests cursor for
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME LIKE 'pct%' AND TABLE_NAME LIKE 'TestData%'

open Tests
fetch next from Tests into @test
while @@fetch_status = 0
BEGIN
  set @cmd = N'exec sp_rename ' + @test + N',' + RIGHT(@test,LEN(@test)-3) + '_Pct' + N', column' 

  print @cmd

  EXEC sp_executeSQL @cmd

  fetch next from Tests into @test
END

close Tests 
deallocate Tests


ROLLBACK TRANSACTION
--COMMIT TRANSACTION

编辑 2 - 该脚本旨在重命名名称与模式匹配的列,在本例中使用“pct”前缀。这些列出现在数据库中的各种表中。所有表名都以“TestData”为前缀。

【问题讨论】:

  • 此行连接一个字符串。你为什么不把它打印出来,这样你就可以看到字符串的内容是什么,
  • 如果@test 包含限定名称,则它需要使用撇号。如果相同的假设成立,right() 将删除表名中的前三个字符;在您想替换列名的最后一个字符时,这将是LEFT。您能否通过添加 set @test = ... 来扩展脚本?
  • 您的代码实际上帮助我解决了我的问题 - 谢谢!

标签: tsql sql-server-2005


【解决方案1】:

这里是稍加修改的版本。更改会在代码注释中注明。

BEGIN TRANSACTION

declare @cnt int
declare @test nvarchar(128)
-- variable to hold table name
declare @tableName nvarchar(255)
declare @cmd nvarchar(500) 
-- local means the cursor name is private to this code
-- fast_forward enables some speed optimizations
declare Tests cursor local fast_forward for
 SELECT COLUMN_NAME, TABLE_NAME
   FROM INFORMATION_SCHEMA.COLUMNS 
  WHERE COLUMN_NAME LIKE 'pct%' 
    AND TABLE_NAME LIKE 'TestData%'

open Tests
-- Instead of fetching twice, I rather set up no-exit loop
while 1 = 1
BEGIN
  -- And then fetch
  fetch next from Tests into @test, @tableName
  -- And then, if no row is fetched, exit the loop
  if @@fetch_status <> 0
  begin
     break
  end
  -- Quotename is needed if you ever use special characters
  -- in table/column names. Spaces, reserved words etc.
  -- Other changes add apostrophes at right places.
  set @cmd = N'exec sp_rename ''' 
           + quotename(@tableName) 
           + '.' 
           + quotename(@test) 
           + N''',''' 
           + RIGHT(@test,LEN(@test)-3) 
           + '_Pct''' 
           + N', ''column''' 

  print @cmd

  EXEC sp_executeSQL @cmd
END

close Tests 
deallocate Tests

ROLLBACK TRANSACTION
--COMMIT TRANSACTION

【讨论】:

  • SO 中我最喜欢的答案之一。
  • @RubensMariuzzo 谢谢,你太慷慨了 :-)
  • TLDR; FETCH NEXT FROM db_cursor INTO @var1, @var2
  • TLDR 通常用于表示较长信息的简短版本。它代表太久没有阅读。我的意思是你给出的答案有一个更短的版本,我给出了它。
  • 不错的触感,没有抓取两次。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-25
  • 2021-09-24
  • 2015-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-28
相关资源
最近更新 更多