web-dev-qa-db-fra.com

Comprendre les sys.objects, sys.system_objects et sys.sysobjects?

Dans cette question J'écrivais une requête en utilisant sys.sysobjects. Cependant, l'une des réponses mentionnées sys.system_objects. Je me demande juste quelle est la différence entre ces tables?

  • sys.objects
  • sys.system_objects
  • sys.sysobjects

sysobjects a plus de choses.

> SELECT count(*) FROM sysobjects;
2312

> SELECT count(*) FROM sys.system_objects;
2201

> SELECT count(*) FROM sys.objects;
> 111

SELECT count(*)
FROM sys.sysobjects
WHERE NOT EXISTS (
  SELECT 1
  FROM sys.system_objects
  WHERE system_objects.object_id = sysobjects.id
);
> 111
6
Evan Carroll

Microsoft Parlance

Pour démarrer, Microsoft a trois catégories pertinentes pour cette discussion,

Application

  • sys.sysschobjs , SYSTEM TABLE, Tous les objets de SQL Server sont représentés dans cette table système. Cette table système a sa propre vue appelée sys.sysschobjs$ Qui prend les chaînes de bits internes et les développe dans les colonnes bit. Deux vues de catalogue tirées de sys.sysschobjs$ Contre sys.syspalnames ON syspalnames.class = 'OBTY' Sont,

    • sys.system_objects , OBJECT CATALOG VIEW. Décrétée par Microsoft, désignée comme système, et identifiée par leur installation dans le schéma sys. Ils obtiennent un qualificatif "Système" explicite dans le langage. En interne, c'est has_access('CO', o.id)

    • sys.objects , OBJECT CATALOG VIEW. Tous les autres objets sont des objets non-système, ce qui est implicite. Lorsque vous voyez objects (juxtaposé avec des objets système), pensez aux objets non-système. En interne, c'est has_access('SO', o.id)

  • sys.sysobjects , Affichage de compatibilité. Nommé de manière trompeuse car la désignation sys ici est maladroite lorsque la vue elle-même extrait des objets non sys. Je soupçonne à un moment donné qu'il n'y avait aucune désignation entre les objets système et non système et ils étaient tous sysobjects. Maintenant que la désignation est là, cela est devenu une "vue de compatibilité". Bien que d'autres réponses impliquent qu'il s'agit d'un UNION ALL Qui est strictement incorrect.

    • Il interroge sys.sysschobjs Directement et fournit des informations que les autres vues de catalogue ont supprimées, comme uid.
    • En interne, c'est has_access('MO', id) (pas encore sûr des ramifications)
    • type, userstat et systat sont tous ajoutés ici, et ce que la vue de compatibilité appelle category est extrêmement bizarre et peut-être pas utilisé ailleurs. xtype est le type non altéré de sys.sysschobjs$

Notes de bas de page

Je crois que le sch dans sysschobjs représente le schéma. C'est un autre anti-mnémonique, oubliez-le car il stocke des choses qui ne sont pas dans le schéma sys. Pour cela, vous avez besoin de sys.system_objects.

2
Evan Carroll

Comme indiqué dans mon précédent post sys.sysobjects est obsolète:

Remarque tirée de sys.sysobjects (Transact-SQL)

Cette table système SQL Server 2000 est incluse en tant que vue de compatibilité descendante. Nous vous recommandons d'utiliser à la place les vues système SQL Server actuelles. Pour trouver la ou les vues système équivalentes, consultez Mappage des tables système aux vues système (Transact-SQL) . Cette fonctionnalité sera supprimée dans une future version de Microsoft SQL Server. Évitez d'utiliser cette fonctionnalité dans de nouveaux travaux de développement et prévoyez de modifier les applications qui utilisent actuellement cette fonctionnalité.

Vous devez maintenant combiner sys.system_objects et sys.objects pour récupérer tous les éléments stockés dans le _ sys.sysobjects table système.

SELECT * FROM sys.system_objects 
UNION ALL
SELECT * FROM sys.objects AS o

Résultat:

(2171 row(s) affected)
  • sys.system_objects

    Contient une ligne pour tous les objets système à portée de schéma inclus avec Microsoft SQL Server. Tous les objets système sont contenus dans les schémas nommés sys ou INFORMATION_SCHEMA.

  • sys.objects

    Contient une ligne pour chaque objet défini par l'utilisateur et de portée de schéma créé dans une base de données, y compris une fonction définie par l'utilisateur scalaire compilée en mode natif

Par exemple sp_MScleanupmergepublisher est ìs_ms_shipped mais pas dans le schéma sys (il est dans dbo) donc c'est dans sys.objects et pas sys.system_objects. C'est peut-être parce qu'il s'agit d'un Shell pour sys.sp_MScleanupmergepublisher_internal et est probablement défini lors de la création de l'instance. Si vous avez SSMS, cliquez avec le bouton droit sur dbo.sp_MScleanupmergepublisher procédure stockée système, puis sélectionnez Modifier :

USE [master]
GO
/****** Object:  StoredProcedure [dbo].[sp_MScleanupmergepublisher]    Script Date: 19.12.2017 12:12:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER procedure [dbo].[sp_MScleanupmergepublisher]
as
    exec sys.sp_MScleanupmergepublisher_internal
11
John aka hot2use

Voici la différence:

  • sys.sysobjects Est une ancienne table système SQL Server 2000 (vue de compatibilité). À partir de SQL Server 2005, Microsoft a introduit un nouvel ensemble de vues appelé vues de catalogue en remplacement des vues de compatibilité. Les vues de compatibilité sont toujours dans SQL Server pour la compatibilité descendante (Microsoft a décidé de laisser les anciennes vues pour ne pas casser certains codes internes).

  • sys.system_objects Est une vue de catalogue. Vous pouvez vérifier la définition de l'objet en exécutant ceci: SELECT OBJECT_DEFINITION(OBJECT_ID('sys.system_objects'))

Dans la vue du catalogue, vous pouvez voir qu'ils utilisent la table système sys.sysschobjs:

CREATE VIEW sys.system_objects 
AS   
SELECT o.name,    
o.id AS object_id,    
convert(int, null) AS principal_id,    
o.nsid AS schema_id,    convert(int, 0) AS parent_object_id,    
o.type,    
n.name AS type_desc,    
o.created AS create_date,    
o.modified AS modify_date,    
convert(bit, 1) AS is_ms_shipped,    
convert(bit, 0) AS is_published,    
convert(bit, 0) AS is_schema_published   
FROM sys.sysschobjs o   
LEFT JOIN sys.syspalnames n ON n.class = 'OBTY' AND n.value = o.type   WHERE has_access('SO', o.id) = 1 

En extrayant de sys.objects, Vous pouvez trouver le sys.sysschobjs

SELECT name, type_desc FROM sys.objects
WHERE name = 'sysschobjs' 

Le tableau système ci-dessous nécessite l'accès DAC

+------------+--------------+
| name       | type_desc    |
+------------+--------------+
| sysschobjs | SYSTEM_TABLE |
+------------+--------------+

Vous pouvez trouver les vues de catalogue en exécutant:

SELECT * 
FROM sys.all_views
WHERE [schema_id] = 4 AND [name] NOT LIKE 'dm%' AND [object_id] NOT IN (-212,-211,-210,-209,-208,-207,-206,-205,-204,-203,-202,-201,-200,-199,-198,-197,-196,-195,-194,-193,-192,-143,-142,-141,-140,-139,-138,-137,-136,-135,-134,-133,-132,-131,-130,-129,-106,-105)
ORDER BY [name] ASC

Et Microsoft docs ici

vous pouvez consulter d'autres tables système et comparer comme:

  • sys.databases (SQL Server 2005 et versions ultérieures)
  • sys.sysdatabases (SQL Server 2000)

Microsoft ne nous encourage pas à utiliser les anciennes tables système. Les anciennes vues de compatibilité n'ont pas les nouvelles métadonnées liées à la version supérieure des fonctionnalités de SQL Server (par exemple, le partitionnement, etc.). Utilisez-le uniquement sur SQL Server 2000 car Microsoft le supprimera de la future version de SQL Server.

4
user37701