2012-06-14 10 views
56

Khi tôi cố gắng để chạy các đoạn mã SQL sau bên trong một vòng lặp con trỏ,Làm cách nào để tìm nạp nhiều cột để sử dụng 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 thông báo sau,

Msg 15.248, Level 11, State 1, Thủ tục sp_rename, Line 213
Tham số @objname không rõ ràng hoặc được xác nhận @objtype (COLUMN) là sai.

Điều gì là sai và cách khắc phục? Tôi đã thử bọc tên cột trong ngoặc đơn [] và dấu ngoặc kép "" giống như một số kết quả tìm kiếm được đề xuất.

Chỉnh sửa 1 -

Đây là toàn bộ tập lệnh. Làm cách nào để chuyển tên bảng thành sp đổi tên? Tôi không chắc chắn làm thế nào để làm điều đó vì các tên cột nằm trong 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ột có tên khớp với mẫu, trong trường hợp này có tiền tố "pct". Các cột xuất hiện trong một loạt các bảng trong cơ sở dữ liệu. Tất cả các tên bảng được bắt đầu bằng "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 nội dung của chuỗi là gì, –

+0

'@ test' có [dạng' table.column' hoặc 'schema.table.column'] (http://msdn.microsoft) .com/vi-us/library/ms188351.aspx), phải không? – GSerg

+0

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

Trả lời

96

Dưới đây là một chút thay đổi phiên bản. Các thay đổi được ghi nhận là 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 
+0

Một trong những câu trả lời yêu thích của tôi trong SO. –

+0

@RubensMariuzzo Cảm ơn, bạn đang quá hào phóng :-) –

+32

TLDR; FETCH TIẾP THEO TỪ db_cursor INTO '@ var1,' @ var2 –

-2

Bạn đang nói nó để đổi tên một cột, nhưng nó không có ý tưởng mà bảng rằng cột là trong

sp_rename:.

[ @objname = ] 'object_name'

là dòng điện đủ điều kiện hoặc tên không đủ tiêu chuẩn của đối tượng người dùng hoặc kiểu dữ liệu. Nếu đối tượng được đổi tên là cột trong bảng, object_name phải ở dạng table.column hoặc schema.table.column.

(Nhấn mạnh thêm)