一時テーブルではなく、tempdbではなくユーザーデータベースで#で始まるSQL Serverテーブル名


13

どういうわけか、数十年前に、データベースで始まるテーブルが作成されました#。オブジェクトエクスプローラーでは、アプリのデータベースの下に表示されますが、ではありませんtempdb。何らかの理由で、Azureはこのようなデータベースをインポートしません。

ドロップしたり、名前を変更したり、操作したりすることはできません。オブジェクトエクスプローラーからの削除スクリプトドロップ、GUIからの名前変更を試みましたが、いずれも機能しませんでした。

SQL 2008 R2を使用しています。

drop table [*app*].[dbo]."#OBSOLETE";

Database name '*app*' ignored, referencing object in tempdb.
Msg 3701, Level 11, State 5, Line 1
Cannot drop the table '#OBSOLETE', because it does not exist or you do not 
have permission.

exec sp_rename "dbo.#OBSOLETE", "dbo.obsolete"

Msg 15225, Level 11, State 1, Procedure sp_rename, Line 338
No item by the name of 'dbo.#OBSOLETE' could be found in the current database '*app*', given that @itemtype was input as '(null)'.

これをAzureに移行できるように、このオブジェクトを強制終了するにはどうすればよいですか?


4
テーブル名をブラケットで囲んでみてください、同じ応答ですか?
rvsc48

1
@ rvsc48のソリューションでうまくいかない場合は、QUOTENAME関数を使用してみてください(できますが)。 docs.microsoft.com/en-us/sql/t-sql/functions/...
MguerraTorres

1
括弧:同じ応答。
それは男

1
このテーブルを含むDBで次のクエリを実行し、出力を質問に貼り付けてください:SELECT [name], CONVERT(VARBINARY(128), [name]) FROM sys.tables WHERE [name] = N'#OBSOLETE';。ありがとう。
ソロモンラツキー

2
別のオプション(テストする時間がない):1)object_idそのテーブルを取得します。2)インスタンスをシングルユーザーモードで再起動します。3) Dedicated Admin Connectionを介して接続します。4)そのDBで、次のようなものを試してくださいUPDATE sys.objects$ SET [name] =N'obsolete' WHERE [object_id] = {ye_olde_object_id}; {enter} GO {enter}。フォートワースショット...
ソロモンRutzky

回答:


16

与えられた:

  1. sp_rename オブジェクトIDの代わりにオブジェクト名を使用します。
  2. オブジェクト名はaで始まり、#特別な意味を持つと解釈され、異なる方法で処理されるため、オブジェクト名は使用できません。
  3. 他のすべてのオプションは使い果たされています

専用の管理コンソール(DAC)接続を介して、基になるシステムカタログテーブルを直接編集してみてください。

  1. object_idそのテーブルを取得します。
  2. シングルユーザーモードでインスタンスを再起動します。これは、システムテーブルを直接更新できるようにするためです(つまり、DAC接続を使用するための要件ではありません)。
  3. 専用管理コンソール接続を介して接続します。コマンドプロンプトウィンドウで次のコマンドを実行することにより、SQLCMDインタラクティブセッションでこれを行うことができます。

    C:\> SQLCMD -A -E

    または、次を使用してDBに直接接続します。

    C:\> SQLCMD -A -E -d {database_name}
  4. そのDBで、次のようなものを試してください。

    UPDATE sys.objects$ {enter}
    SET [name] = N'obsolete' {enter}
    WHERE [object_id] = {ye_olde_object_id}; {enter}
    GO {enter}

    を入力するまで、ステートメントは実行されませんGO {enter}

システムカタログテーブルを直接編集するときは注意してください。また、それを行うことにあまり慣れないでください。これは、他の方法で問題を修正する方法がまったくない場合(ここの場合など)にのみ行うべきことです。直接編集を行わないようにする理由はおそらくいくつかありますが、最初に思い浮かぶのは次の2つです。

  • 私たちが作成するデータモデルと同様に、物事がどのように機能するかを知らないルールやワークフローがあります(非正規化、さまざまなテーブルのデータの状態を管理する「ビジネス」ルールなど)
  • 直接編集を行うと、問題が発生してサポート契約を結んでいる場合にサポートするマイクロソフトの責任が無効になる可能性が高くなります(サポート契約の条件は確認していませんが、そのような言語は含まれないと信じるのに苦労しています)そこ)

    @Paul Randalは、私の関連する回答のコメントで確認しました。「システムテーブルを手動で編集すると、データベースのブートページにフラグが設定され、データベースがこのように編集されたとマークされ、CSSその後そのデータベースで問題が発生した場合は、」


4
私は答えが好きですが、なぜこれがとても危険なのかについて文を追加する価値があるのでしょうか?
ジョーオブビッシュ

@JoeObbishありがとう、良い提案。明日何かを追加しようとします。
ソロモンラッツキー

2
@JoeObbish何かを追加しました。それで十分ですか?
ソロモンラツキー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.