Nama tabel SQL Server dimulai dengan # di basis data pengguna, bukan di tempdb, bukan tabel temp

13

Entah bagaimana, beberapa dekade yang lalu, sebuah tabel dibuat di basis data kami yang dimulai dengan a #. Itu muncul di Object Explorer di bawah database aplikasi, bukan di tempdb. Untuk beberapa alasan, Azure tidak akan mengimpor basis data seperti ini.

Kami tidak dapat menjatuhkannya, mengganti nama, atau berinteraksi dengannya. Saya sudah mencoba Hapus dari Object Explorer, Drop Script , Ganti nama dari GUI dan tidak ada yang bekerja.

Kami menggunakan 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)'.

Bagaimana cara kita membunuh objek ini sehingga kita bisa memigrasi ini ke Azure?

pria itu
sumber
4
Coba letakkan tanda kurung di sekeliling nama tabel, respons yang sama?
rvsc48
1
Bisakah Anda mencoba menggunakan fungsi QUOTENAME jika solusi @ rvsc48 tidak melakukannya (walaupun saya pikir itu akan). docs.microsoft.com/en-us/sql/t-sql/functions/…
MguerraTorres
1
Kurung: respons yang sama.
pria itu
1
Jalankan query berikut di DB yang berisi tabel ini dan paste output ke pertanyaan: SELECT [name], CONVERT(VARBINARY(128), [name]) FROM sys.tables WHERE [name] = N'#OBSOLETE';. Terima kasih.
Solomon Rutzky
2
Opsi lain (yang saya tidak punya waktu untuk menguji): 1) Dapatkan object_idtabel itu. 2) Mulai ulang instance dalam mode pengguna tunggal. 3) terhubung melalui Koneksi Admin Khusus. 4) Dalam DB itu, coba sesuatu seperti UPDATE sys.objects$ SET [name] =N'obsolete' WHERE [object_id] = {ye_olde_object_id}; {enter} GO {enter}. Layak dicoba ..
Solomon Rutzky

Jawaban:

16

Diberikan:

  1. sp_rename menggunakan nama objek, bukan ID objek,
  2. kita tidak dapat menggunakan nama objek karena dimulai dengan #dan yang ditafsirkan memiliki makna khusus dan ditangani secara berbeda,
  3. semua opsi lain telah habis

Anda harus mencoba mengedit tabel katalog sistem yang mendasarinya secara langsung melalui koneksi Dedicated Admin Console (DAC) :

  1. Dapatkan object_idtabel itu.
  2. Mulai ulang instance dalam mode Pengguna Tunggal. Ini harus dapat secara langsung memperbarui tabel sistem (yaitu bukan persyaratan untuk menggunakan koneksi DAC).
  3. Terhubung melalui koneksi Konsol Admin Khusus. Anda dapat melakukan ini dalam sesi interaktif SQLCMD dengan menjalankan yang berikut di jendela Prompt Perintah:

    C:\> SQLCMD -A -E

    atau, hubungkan langsung ke DB menggunakan:

    C:\> SQLCMD -A -E -d {database_name}
  4. Di DB itu, coba sesuatu seperti berikut:

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

    Itu tidak akan menjalankan pernyataan sampai Anda memasukkan GO {enter}.

Harap berhati-hati ketika langsung mengedit tabel katalog sistem, dan jangan terlalu nyaman dengan ide untuk melakukannya. Ini adalah sesuatu yang harus dilakukan hanya jika sama sekali tidak ada cara lain untuk memperbaiki masalah (seperti kasus di sini). Mungkin ada beberapa alasan untuk menghindari penyuntingan langsung, tetapi dua yang awalnya muncul di pikiran adalah:

  • Sama seperti model-data yang kita buat, ada kemungkinan aturan dan alur kerja untuk cara kerja hal-hal yang tidak kita sadari (misalnya denasionalisasi, aturan "bisnis" yang mengatur keadaan data di berbagai tabel, dll)
  • Kemungkinan besar melakukan penyuntingan langsung mengosongkan tanggung jawab Microsoft untuk membantu Anda jika Anda mengalami masalah dan memiliki kontrak dukungan (Saya belum melihat ketentuan-ketentuan perjanjian Dukungan, tetapi saya sulit percaya bahwa bahasa seperti itu tidak akan ada dalam sana)

    @ Paul Randal dikonfirmasi dalam komentar pada jawaban terkait saya: "secara manual mengedit tabel sistem secara tidak dapat dibatalkan menetapkan bendera di halaman boot database yang menandai database Anda telah diedit dengan cara ini, dan CSS mungkin memutuskan untuk tidak membantu Anda jika Anda kemudian memiliki masalah dengan database itu. "

Solomon Rutzky
sumber
4
Saya suka jawabannya, tetapi mungkin perlu menambahkan kalimat mengapa ini sangat berbahaya untuk dilakukan?
Joe Obbish
@ Jooboh Terima kasih, dan saran yang bagus. Saya akan mencoba menambahkan sesuatu besok.
Solomon Rutzky
2
@ Joobhish Aku baru saja menambahkan sesuatu. Apakah itu cukup?
Solomon Rutzky