Nom de table SQL Server commençant par # dans la base de données utilisateur, pas dans tempdb, pas une table temporaire

13

Il y a quelques décennies, une table a été créée dans notre base de données qui commence par un #. Il apparaît dans l'Explorateur d'objets sous la base de données de l'application, pas dans tempdb. Pour une raison quelconque, Azure n'importera pas la base de données comme ceci.

Nous ne pouvons pas le supprimer, le renommer ou interagir avec lui. J'ai essayé Supprimer de l'Explorateur d'objets, Script Drop , Renommer de l'interface graphique et aucun d'entre eux n'a fonctionné.

Nous sommes sur 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)'.

Comment tuer cet objet pour pouvoir le migrer vers Azure?

ce gars
la source
4
Essayez de mettre des crochets autour du nom de la table, même réponse?
rvsc48
1
Pouvez-vous essayer d'utiliser la fonction QUOTENAME si la solution de @ rvsc48 ne le fait pas (bien que je pense que oui). docs.microsoft.com/en-us/sql/t-sql/functions/…
MguerraTorres
1
Supports: même réponse.
que ce gars
1
S'il vous plaît exécuter la requête suivante dans la base de données contenant ce tableau et collez la sortie dans la question: SELECT [name], CONVERT(VARBINARY(128), [name]) FROM sys.tables WHERE [name] = N'#OBSOLETE';. Merci.
Solomon Rutzky
2
Une autre option (que je n'ai pas le temps de tester): 1) Obtenez le object_idde cette table. 2) Redémarrez l'instance en mode mono-utilisateur. 3) connectez-vous via une connexion administrateur dédiée. 4) Dans cette BD, essayez quelque chose comme UPDATE sys.objects$ SET [name] =N'obsolete' WHERE [object_id] = {ye_olde_object_id}; {enter} GO {enter}. Vaut le coup ..
Solomon Rutzky

Réponses:

16

Donné:

  1. sp_rename utilise des noms d'objet au lieu d'ID d'objet,
  2. nous ne pouvons pas utiliser le nom de l'objet car il commence par un #et qui est interprété comme ayant une signification spéciale et est géré différemment,
  3. toutes les autres options ont été épuisées

Vous devez essayer de modifier la table du catalogue système sous-jacent directement via une connexion DAC (Dedicated Admin Console) :

  1. Obtenez le object_idde cette table.
  2. Redémarrez l'instance en mode mono-utilisateur. Il s'agit de pouvoir mettre à jour directement les tables système (c'est-à-dire qu'il n'est pas nécessaire d'utiliser la connexion DAC).
  3. Connectez-vous via la connexion de la console d'administration dédiée. Vous pouvez le faire dans une session interactive SQLCMD en exécutant ce qui suit dans une fenêtre d'invite de commandes:

    C:\> SQLCMD -A -E

    ou connectez-vous directement à la base de données en utilisant:

    C:\> SQLCMD -A -E -d {database_name}
  4. Dans cette base de données, essayez quelque chose comme ceci:

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

    Il n'exécutera pas l'instruction tant que vous n'aurez pas mis le fichier GO {enter}.

Soyez prudent lorsque vous éditez directement des tables de catalogue système, et ne soyez pas trop à l'aise avec l'idée de le faire. C'est quelque chose qui ne devrait être fait que s'il n'y a absolument aucun autre moyen de résoudre un problème (comme le cas ici). Il y a probablement plusieurs raisons d'éviter de faire des modifications directes, mais les deux qui me viennent à l'esprit au départ sont:

  • Tout comme les modèles de données que nous créons, il existe probablement des règles et des workflows pour le fonctionnement des choses que nous ignorons (par exemple dénormalisation, règles "métier" régissant l'état des données sur différentes tables, etc.)
  • Il est très probable que des modifications directes annulent la responsabilité de Microsoft de vous aider si vous rencontrez des problèmes et si vous avez un contrat de support (je n'ai pas vu les termes des accords de support, mais j'ai du mal à croire qu'une telle langue ne serait pas en Là)

    @Paul Randal a confirmé dans un commentaire sur une réponse connexe : "la modification manuelle d'une table système définit irrévocablement un indicateur dans la page de démarrage de la base de données qui marque votre base de données comme ayant été modifiée de cette manière, et CSS pourrait décider de ne pas aider vous si vous rencontrez par la suite des problèmes avec cette base de données. "

Solomon Rutzky
la source
4
J'aime la réponse, mais cela vaut peut-être la peine d'ajouter une phrase expliquant pourquoi c'est si dangereux de le faire?
Joe Obbish
@JoeObbish Merci et bonne suggestion. J'essaierai d'ajouter quelque chose demain.
Solomon Rutzky
2
@JoeObbish Je viens d'ajouter quelque chose. Est-ce suffisant?
Solomon Rutzky