web-dev-qa-db-fra.com

Le schéma par défaut permet la sélection de la table DBO sans utiliser de préfixe de schéma

J'ai créé un identifiant et un utilisateur de base de données sur mon serveur comme suit:

USE master
GO
CREATE LOGIN MyLogin WITH PASSWORD=N'Password123!'
GO
USE AdventureWorks2014
GO
CREATE USER MyLogin FOR LOGIN MyLogin
GO
ALTER USER MyLogin WITH DEFAULT_SCHEMA=HumanResources
GO
GRANT SELECT ON SCHEMA :: Production TO MyLogin
GO
GRANT SELECT ON SCHEMA :: HumanResources TO MyLogin
GO
GRANT SELECT ON SCHEMA :: dbo TO MyLogin

Lorsque je me connecte en tant que mylogin, je peux maintenant sélectionner des objets dans le schéma HumanResources sans utiliser le nom de quatre pièces (comme humanResources est le schéma par défaut de cet utilisateur)

SELECT * FROM HumanResources.Department

peut maintenant être exécuté sans le nom du schéma:

SELECT * FROM Department

C'est bon. Si j'essaie ensuite de choisir parmi une table dans le schéma de production sans utiliser le préfixe de schéma:

SELECT * FROM ProductDescription

Je reçois une erreur comme prévu. Cela peut être corrigé en utilisant:

SELECT * FROM Production.ProductDescription

Ainsi, en fonction de cela, je dois spécifier le nom du schéma lors de la sélection de n'importe quelle table en dehors du schéma par défaut.

Alors, pourquoi quand je sélectionne depuis une table dans le schéma DBO, n'est-ce pas toujours nécessaire d'utiliser le préfixe de schéma?

SELECT * FROM DatabaseLog

renvoie les résultats

Je suis confus. Je pensais que si un nom de schéma ne préfixe pas la table dans une instruction SELECT, que le schéma par défaut est utilisé et la sélection d'une table dans tout autre schéma nécessiterait le préfixe de schéma.

Le schéma DBO est-il une exception à cette règle?

3
SEarle1986

Vous n'avez pas besoin du préfixe lorsque un objet est dans votre schéma par défaut, car SQL Server vérifie d'abord un objet non-archa-préfixé dans votre schéma par défaut. Il vérifiera ensuite le schéma dbo, afin que vous puissiez réellement vous échapper avec cette paresse de deux manières différentes.

De - la documentation :

Lorsque des objets de base de données sont référencés à l'aide d'un nom d'une pièce, SQL Server regarde d'abord dans le schéma par défaut de l'utilisateur. Si l'objet n'est pas trouvé présent, SQL Server regarde ensuite dans le schéma dbo. Si l'objet n'est pas dans le schéma dbo, une erreur est renvoyée.

Ils disent "nom d'une pièce" mais cela s'applique également lorsque vous faites référence à un objet avec un motif de type:

[server].[database]..[name]

ou alors

[database]..[name]

Ce n'est que une confirmation que vous devriez simplement spécifier toujours le nom du schéma. toujours.

6
Aaron Bertrand