Nome da tabela do SQL Server começando com # no banco de dados do usuário, não no tempdb, não em uma tabela temporária

13

De alguma forma, décadas atrás, uma tabela foi criada em nosso banco de dados que começa com a #. Ele aparece no Pesquisador de Objetos, no banco de dados do aplicativo, e não no tempdb. Por algum motivo, o Azure não importará o banco de dados como este.

Não podemos descartá-lo, renomeá-lo ou interagir com ele. Eu tentei Delete from Object Explorer, Script Drop , Rename from GUI e nenhum deles funcionou.

Estamos no 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)'.

Como matamos esse objeto para podermos migrar para o Azure?

que cara
fonte
4
Tente colocar colchetes ao redor do nome da tabela, mesma resposta?
rvsc48
1
Você pode tentar usar a função QUOTENAME se a solução da @ rvsc48 não fizer isso (embora eu ache que sim). docs.microsoft.com/en-us/sql/t-sql/functions/…
MguerraTorres
1
Parênteses: mesma resposta.
que cara
1
Por favor, execute a seguinte consulta no banco de dados que contém esta tabela e colar a saída em questão: SELECT [name], CONVERT(VARBINARY(128), [name]) FROM sys.tables WHERE [name] = N'#OBSOLETE';. Obrigado.
Solomon Rutzky
2
Outra opção (que não tenho tempo para testar): 1) Pegue a object_idtabela. 2) Reinicie a instância no modo de usuário único. 3) conecte-se via Conexão de administrador dedicada. 4) Nesse banco de dados, tente algo parecido UPDATE sys.objects$ SET [name] =N'obsolete' WHERE [object_id] = {ye_olde_object_id}; {enter} GO {enter}. Pena um tiro ..
Solomon Rutzky

Respostas:

16

Dado:

  1. sp_rename usa nomes de objetos em vez de IDs de objetos,
  2. não podemos usar o nome do objeto, pois ele começa com a #e é interpretado como tendo um significado especial e tratado de maneira diferente,
  3. todas as outras opções foram esgotadas

Você deve tentar editar a tabela de catálogo do sistema subjacente diretamente por meio de uma conexão do Console de administração dedicada (DAC) :

  1. Pegue a object_idtabela.
  2. Reinicie a instância no modo de usuário único. Isso deve ser capaz de atualizar diretamente as tabelas do sistema (ou seja, não é um requisito para o uso da conexão DAC).
  3. Conecte-se via conexão Dedicated Admin Console. Você pode fazer isso em uma sessão interativa SQLCMD executando o seguinte em uma janela do Prompt de Comando:

    C:\> SQLCMD -A -E

    ou conecte-se diretamente ao banco de dados usando:

    C:\> SQLCMD -A -E -d {database_name}
  4. Nesse banco de dados, tente algo como o seguinte:

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

    Não executará a instrução até que você coloque o GO {enter}.

Seja cauteloso ao editar diretamente as tabelas de catálogos do sistema e não fique muito à vontade com a ideia de fazê-lo. Isso é algo que deve ser feito apenas se não houver absolutamente nenhuma outra maneira de corrigir um problema (como o caso aqui). Provavelmente, existem várias razões para evitar edições diretas, mas as duas que vêm à mente são:

  • Assim como os modelos de dados que criamos, existem regras e fluxos de trabalho prováveis ​​de como as coisas não são conhecidas (por exemplo, desnormalização, regras "comerciais" que governam o estado dos dados em várias tabelas, etc.)
  • Provavelmente, fazer edições diretas anula a responsabilidade da Microsoft em ajudá-lo se você tiver problemas e tiver um contrato de suporte (eu não vi os termos do (s) contrato (s) de Suporte, mas tenho dificuldade em acreditar que esse idioma não esteja dentro há)

    @ Paul Randal confirmou em um comentário em uma resposta minha: "editar manualmente uma tabela do sistema irrevogavelmente define um sinalizador na página de inicialização do banco de dados que marca seu banco de dados como tendo sido editado dessa maneira, e o CSS pode decidir não ajudar você se tiver problemas subsequentes com esse banco de dados ".

Solomon Rutzky
fonte
4
Gosto da resposta, mas talvez valha a pena acrescentar uma frase sobre por que isso é tão perigoso de se fazer?
Joe Obbish
@ JoeObbish Obrigado, e boa sugestão. Vou tentar adicionar algo amanhã.
Solomon Rutzky
2
@JoeObbish Acabei de adicionar algo. Isso é suficiente?
Solomon Rutzky