Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Perché (e come) dividere la colonna usando master..spt_values?

Scopo

Perché usare master..spt-values non documentati

Sybase, e quindi il suo figlio bastardo MS SQL, fornisce varie caratteristiche e funzioni per il prodotto, che viene implementato nelle procedure di sistema (al contrario dei binari come sqlserver, che vengono avviati come servizio). Queste procedure di sistema sono scritte in codice SQL e denominate sp_%. Fatta eccezione per alcuni interni segreti, hanno le stesse limitazioni e necessità di qualsiasi altro codice SQL. Fanno parte del prodotto Sybase ASE o SQL Server. In quanto tali, non sono richiesti per documentarlo; e i bit interni non possono essere ragionevolmente etichettati come "non documentati".

master..spt_values contiene tutti i vari bit e pezzi di cui le suddette procedure di sistema necessitano, in una tabella SQL, per produrre i vari report. Il sp significa procedura di sistema; spt indica le tabelle per le procedure di sistema; e ovviamente values è il contenuto.

Tabelle di ricerca

Qual ​​è il (significato di) Tipo ='P'

Le persone spesso descrivono spt_values come "denormalizzato", ma questo è il termine errato. Il termine corretto è piegato o imballato . Sono circa 26 tabelle di ricerca logiche, ognuna splendidamente normalizzata, ripiegata in una tabella fisica, con un Type colonna per differenziare le tabelle logiche.

Ora in un normale database, sarebbe un errore grossolano (basta guardare le risposte per "una tabella di ricerca o molte"). Ma in un catalogo server, è auspicabile che sostituisca 26 tabelle fisiche.

  • "L" sta per LockType Lookup; "V" sta per DeviceType Lookup (V è l'abbreviazione di Device in tutto il server); ecc. Digitare "P2" contiene ordinali bit per bit, per l'espansione dei bit che sono impacchettati in un INT.

  • È necessario un insieme di numeri consecutivi entro limiti noti, disponibile sotto forma di tabella SQL, per eseguire una proiezione, cosa che devono fare molte delle procedure di sistema. Digitare "P" è un elenco di numeri consecutivi compresi tra 0 e 2047.

  • Il termine Proiezione è qui usato come significato tecnicamente preciso, senso logico naturale, non significato di algebra relazionale, che è innaturale.

C'è quindi un solo scopo per spt_values, per contenere 26 tavole di riferimento piegate, altrimenti separate, e una tavola di proiezione.

Espansione

L'uso ordinario di spt_values quindi, è come una normale ricerca o riferimento o ENUM tavolo. Innanzitutto, i valori di ricerca:

    SELECT *                    -- list Genders
        FROM Gender 

Viene utilizzato nello stesso modo in cui Person ha un GenderCode che deve essere ampliato (molto ampliato, in questi giorni bizzarri):

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

Per esempio. sp_lock produce un rapporto sui blocchi attivi, visualizzando i tipi di blocco come nomi stringa . Ma master..syslocks contiene tipi di blocco come numeri , non contiene quei nomi; e se lo facesse, sarebbe un tavolo gravemente denormalizzato! Se esegui la query (codice Sybase ASE, dovrai convertire):

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

noterai 66 numeri LockType e nomi nella tabella di ricerca. Ciò consente sp_lock per eseguire codice semplice come Person::Gender sopra:

    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

Proiezione

Qual ​​è il (significato di) Type ='P' ?

Che cos'è Projection e come viene utilizzato?

Supponiamo, ad esempio, che invece dei blocchi attivi prodotti dalla query precedente, desideri un elenco di tutti 66 LockTypes, che mostra il numero di lock attivi (o Null). Non hai bisogno di un cursore o di un WHILE ciclo continuo. Potremmo Progetto la tabella di ricerca LockType, attraverso il conteggio delle serrature attive:

    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"

Ci sono diversi metodi, questo è solo uno. Un altro metodo consiste nell'utilizzare una tabella derivata anziché la sottoquery. Ma hai ancora bisogno della proiezione.

Questo è in genere ciò che spt_values viene utilizzato per Espansione o Proiezione. Ora che sai che c'è, puoi usarlo anche tu. È sicuro (nel master database) e utilizzato praticamente da tutte le procedure di sistema, il che significa che le procedure di sistema non possono essere eseguite senza di essa.

per dividere una colonna?

Ah, non capisci il codice "Dividi una colonna CSV in più righe".

  • Dimentica spt_values per un momento, ed esaminare di nuovo quel codice. Ha solo bisogno di un elenco di numeri consecutivi, in modo che in possa scorrere l'elenco di valori nella colonna CSV, byte per byte. Il codice viene attivato solo per ogni byte che è una virgola o fine stringa.

  • Dove ottenere un insieme di numeri consecutivi sotto forma di una tabella SQL, invece di CREArne uno da zero e INSERIRE in esso? Perché, master..spt_values Certo. Se sai che c'è.

  • (Puoi imparare qualcosa sugli interni di ASE o SQL Server, semplicemente leggendo il codice delle stored procedure di sistema.)

  • Si noti che qualsiasi campo CSV in una colonna è un errore di normalizzazione grossolano, interrompe 2NF (contiene valori ripetuti) e 1NF (non atomico). Nota che non è imballato o piegato, è un gruppo ripetuto, non è normalizzato. Una delle molte conseguenze negative di un errore così grossolano è che, invece di utilizzare un semplice SQL per navigare nel gruppo ripetuto come righe, è necessario utilizzare un codice complesso per determinare ed estrarre il contenuto del campo CSV non normalizzato. Qui spt_values P fornisce un vettore per quel codice complesso, rendendolo più semplice.

Qual ​​è il vantaggio?

Penso di aver risposto. Se non l'avessi, ogni procedura di sistema che richiede un elenco di numeri dovrebbe CREARE una tabella temporanea; e INSERT le righe al suo interno; prima di eseguire il suo codice. Ovviamente, non dover eseguire questi passaggi, rende le procedure di sistema molto più veloci.

Ora, quando è necessario eseguire una proiezione, ad es. date del calendario in futuro, o qualsiasi altra cosa, puoi utilizzare spt_values , invece di dover creare ogni volta la tua tabella temporanea (o creare la tua tabella permanente privata e mantenerla).