2012-06-14 19 views
56

私は、カーソルループ内で、次のSQLスニペットを実行しようと、私は次のメッセージを取得 カーソルループで使用する複数の列を取得するにはどうすればよいですか?

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 -

以下はスクリプト全体です。テーブル名を名前変更spに渡すにはどうすればよいですか?列名は多くの表の1つにあるので、どのように行うのかは分かりません。

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」が付いています。

+1

この行は文字列を連結します。文字列の内容を見ることができるように、なぜ出力しないのですか? –

+0

'@ test'は[table.column'または' schema.table.column'の形式です](http://msdn.microsoft .com/ja-us/library/ms188351.aspx)、そうですか? – GSerg

+0

@testに修飾名が含まれている場合は、アポストロフィである必要があります。同じ仮定が当てはまる場合、right()はテーブル名の最初の3文字を削除します。列名の最後の文字を置き換えたければ、これは 'LEFT'でしょう。 set @test = ...を追加してスクリプトを少し拡張してください。 –

答えて

96

ここでは、わずかにバージョンを変更されます。変更はコード解説として記録されます。

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

私の好きな答えのひとつです。 –

+0

@RubensMariuzzoありがとう、あなたはあまりにも寛大です:-) –

+32

TLDR; db_cursorからFETCH NEXT INTO '@ var1、' @ var2 –

-2

あなたは列の名前を変更するためにそれを言っているが、それは列がでテーブルでない考えを持っていない

sp_rename:。

[ @objname = ] 'object_name'

は電流Is資格またはユーザーオブジェクトまたはデータ型の非修飾名。 名前を変更するオブジェクトが表内の列である場合、object_nameはtable.columnまたはschema.table.columnの形式である必要があります。

(強調追加)

関連する問題