Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Pourquoi (et comment) diviser la colonne en utilisant master..spt_values ?

Objectif

Pourquoi utiliser des valeurs master..spt-values non documentées

Sybase, et donc son fils bâtard MS SQL, fournissent diverses fonctionnalités et fonctions pour le produit, qui sont implémentées dans les procédures système (par opposition aux binaires comme sqlserver, qui sont démarrés en tant que service). Ces procédures système sont écrites en code SQL et nommées sp_%. À l'exception de certains composants internes secrets, ils ont les mêmes limitations et besoins que tout autre code SQL. Ils font partie du produit Sybase ASE ou SQL Server. En tant que tels, ils ne sont pas obligatoires pour le documenter ; et les bits internes ne peuvent pas être raisonnablement étiquetés comme "non documentés".

master..spt_values contient tous les éléments divers dont lesdites procédures système ont besoin, dans une table SQL, pour produire les différents rapports. Le sp désigne la procédure du système ; spt signifie des tableaux pour les procédures système ; et bien sûr values est le contenu.

Tableaux de recherche

Quelle est la (signification de) Type ='P'

Les gens décrivent souvent spt_values comme "dénormalisé", mais ce n'est pas le bon terme. Le terme correct est plié , ou emballé . Il s'agit d'environ 26 tables de recherche logiques, chacune magnifiquement normalisée, pliée en une seule table physique, avec un Type colonne pour différencier les tables logiques.

Maintenant, dans une base de données normale, ce serait une erreur grossière (il suffit de regarder les réponses pour "une table de recherche ou plusieurs"). Mais dans un catalogue serveur, c'est souhaitable, ça remplace 26 tables physiques.

  • "L" signifie LockType Lookup ; "V" signifie DeviceType Lookup (V est l'abréviation de Device sur tout le serveur) ; etc. Le type "P2" contient des ordinaux au niveau du bit, pour l'expansion des bits qui sont emballés dans un INT.

  • Un ensemble de nombres consécutifs dans des limites connues, disponible sous la forme d'une table SQL, est nécessaire pour effectuer une projection, ce que de nombreuses procédures système doivent faire. Le type "P" est une liste de nombres consécutifs entre 0 et 2047.

  • Le terme Projection est utilisé ici comme le sens techniquement précis, le sens logique naturel, et non le sens de l'algèbre relationnelle, qui n'est pas naturel.

Il n'y a donc qu'un seul but pour spt_values, contenir 26 tables de référence pliées, sinon séparées, et une table de projection.

Extension

L'utilisation ordinaire de spt_values alors, est comme une recherche ou une référence ordinaire ou ENUM table. Tout d'abord, les valeurs de recherche :

    SELECT *                    -- list Genders
        FROM Gender 

Il est utilisé de la même manière que Person a un GenderCode qui doit être étendu (très étendu, de nos jours bizarres) :

    SELECT  P.*,                -- list Person
            G.Name              -- expand GenderCode to Name
        FROM Person P
        JOIN Gender G
            ON P.GenderCode = G.GenderCode

Par exemple. sp_lock produit un rapport des verrous actifs, affichant les types de verrous sous forme de chaîne noms . Mais master..syslocks contient les types de verrous sous forme de chiffres , il ne contient pas ces noms; et si c'était le cas, ce serait une table mal dénormalisée ! Si vous exécutez la requête (code Sybase ASE, vous devrez convertir) :

    SELECT *                    -- list LockTypes
        FROM master..spt_values 
        WHERE type = "L"

vous remarquerez 66 numéros LockType et noms dans la table de recherche. Cela permet sp_lock pour exécuter un code simple comme Person::Gender ci-dessus :

    SELECT  spid,               -- list Active Locks
            DB_NAME(dbid),
            OBJECT_NAME(id, dbid),
            v.name,             -- expand lock name
            page,
            row
    FROM master..syslocks   L,
         master..spt_values LT
    WHERE L.type = LT.number    -- 
    AND   type = "L"            -- LockType Lookup table
    ORDER by 1, 2, 3, 4, 5, 6   -- such that perusal is easy

Projection

Quelle est la (signification de) Type ='P' ?

Qu'est-ce que la projection et à quoi sert-elle ?

Disons, par exemple, qu'au lieu des verrous actifs produits par la requête ci-dessus, vous vouliez une liste de tous 66 LockTypes, indiquant le nombre de verrous actifs (ou Null). Vous n'avez pas besoin d'un curseur ou d'un WHILE boucle. Nous pourrions projeter la table de recherche LockType, à le nombre de verrous actifs :

    SELECT  LT.name,            -- list LockTypes
            [Count] = (         -- with count
        SELECT COUNT(*)
            FROM master..syslocks
            WHERE type = LT.number
                )
        FROM master..spt_values LT
        WHERE type = "L"

Il existe plusieurs méthodes, dont une seule. Une autre méthode consiste à utiliser une table dérivée au lieu de la sous-requête. Mais vous avez toujours besoin de la projection.

C'est généralement ce que spt_values est utilisé pour l'expansion ou la projection. Maintenant que vous savez qu'il est là, vous pouvez aussi l'utiliser. Il est sûr (dans le master base de données) et utilisé par pratiquement toutes les procédures système, ce qui signifie que les procédures système ne peuvent pas s'exécuter sans lui.

pour diviser une colonne ?

Ah, vous ne comprenez pas le code "Split one CSV column into multiple rows".

  • Oubliez les spt_values pendant un moment, et examinez à nouveau ce code. Il a juste besoin d'une liste de nombres consécutifs, de sorte qu'il puisse parcourir la liste de valeurs dans la colonne CSV, octet par octet. Le code est activé uniquement pour chaque octet qui est une virgule ou une fin de chaîne.

  • Où obtenir un ensemble de nombres consécutifs sous la forme d'une table SQL, plutôt que d'en créer une à partir de zéro et de l'INSÉRER ? Pourquoi, master..spt_values bien sûr. Si vous savez qu'il est là.

  • (Vous pouvez en apprendre un peu plus sur les composants internes d'ASE ou de SQL Server, simplement en lisant le code des procédures stockées du système.)

  • Notez que tout champ CSV dans une colonne est une erreur de normalisation grossière, il casse 2NF (contient des valeurs répétitives) et 1NF (non atomique). Remarque, ce n'est pas emballé ou plié, c'est un groupe répétitif, il n'est pas normalisé. L'une des nombreuses conséquences négatives d'une telle erreur grossière est qu'au lieu d'utiliser du SQL simple pour naviguer dans le groupe répétitif sous forme de lignes, il faut utiliser un code complexe pour déterminer et extraire le contenu du champ CSV non normalisé. Ici spt_values P fournit un vecteur pour ce code complexe, ce qui le rend plus facile.

Quel est l'avantage ?

Je pense avoir répondu à cela. Si vous ne l'aviez pas, chaque procédure système qui nécessite une liste de nombres devrait CRÉER une table temporaire ; et INSÉRER les lignes dedans ; avant d'exécuter son code. Bien sûr, ne pas avoir à effectuer ces étapes rend les procédures du système beaucoup plus rapides.

Maintenant, lorsque vous devez effectuer une projection, par ex. dates du calendrier dans le futur, ou quoi que ce soit, vous pouvez utiliser spt_values , au lieu de devoir créer votre propre table temporaire à chaque fois (ou créer votre propre table permanente privée et la maintenir).