Làm cách nào để tìm nạp nhiều cột để sử dụng trong vòng lặp con trỏ?


88

Khi tôi cố gắng chạy đoạn mã SQL sau bên trong vòng lặp con trỏ,

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

Tôi nhận được tin nhắn sau,

Msg 15248, Mức 11, Trạng thái 1, Thủ tục sp_rename, Dòng 213
Hoặc tham số @objnamekhông rõ ràng hoặc xác nhận quyền sở hữu @objtype(COLUMN) là sai.

Điều gì là sai và làm thế nào để tôi sửa chữa nó? Tôi đã thử đặt tên cột trong dấu ngoặc []và dấu ngoặc kép ""như một số kết quả tìm kiếm được đề xuất.

Chỉnh sửa 1 -

Đây là toàn bộ kịch bản. Làm cách nào để chuyển tên bảng sang tên sp? Tôi không chắc làm thế nào để làm điều đó vì tên cột nằm ở một trong nhiều bảng.

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

Chỉnh sửa 2 - Tập lệnh được thiết kế để đổi tên các cột có tên khớp với một mẫu, trong trường hợp này là tiền tố "pct". Các cột xuất hiện trong nhiều bảng trong cơ sở dữ liệu. Tất cả các tên bảng đều có tiền tố là "TestData".


1
dòng này nối một chuỗi. tại sao bạn không in nó ra để bạn có thể xem những gì nội dung của chuỗi là,
Preet Tăng


Nếu @test chứa tên đủ điều kiện, nó cần phải ở trong dấu nháy đơn. Nếu cùng một giả định, right () sẽ xóa ba ký tự đầu tiên trong tên bảng; khi bạn muốn thay thế các ký tự cuối cùng của tên cột, điều này sẽ là LEFT. Bạn có thể vui lòng mở rộng tập lệnh một chút bằng cách thêm set @test = ...?
Nikola Markovinović

Mã của bạn thực sự đã giúp tôi giải quyết vấn đề của mình - cảm ơn vì điều đó!
Neville

Câu trả lời:


156

Đây là phiên bản sửa đổi một chút. Các thay đổi được ghi nhận dưới dạng bình luận mã.

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

2
Một trong những câu trả lời yêu thích của tôi trong SO.
Rubens Mariuzzo 10/12/12

@RubensMariuzzo Cảm ơn, bạn đang quá hào phóng :-)
Nikola Markovinović 10/12/12

61
TLDR; TÌM KIẾM TIẾP THEO TỪ db_cursor VÀO @var1, @ var2
Don Rolling vào

7
TLDR thường được sử dụng để chỉ phiên bản ngắn của một đoạn thông tin dài hơn. Nó là viết tắt của Too Long Did not Read. Tôi đã gợi ý rằng có một phiên bản ngắn hơn của câu trả lời mà bạn đã đưa ra và tôi đã đưa ra.
Don Rolling,

1
Cảm ứng đẹp, không phải tìm nạp hai lần. :)
winner_joiner
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.