sql >> Base de Datos >  >> RDS >> Sqlserver

¿Por qué (y cómo) dividir la columna usando master..spt_values?

Propósito

¿Por qué usar master..spt-values no documentados?

Sybase, y por lo tanto su hijo bastardo MS SQL, proporcionan varias características y funciones para el producto, que se implementan en los procedimientos del sistema (a diferencia de los binarios como sqlserver, que se inician como un servicio). Estos procedimientos del sistema están escritos en código SQL y se denominan sp_%. Excepto por algunos secretos internos, tienen las mismas limitaciones y necesidades que cualquier otro código SQL. Forman parte del producto Sybase ASE o SQL Server. Como tal, no son obligatorios para documentarlo; y los bits internos no pueden etiquetarse razonablemente como "sin documentar".

master..spt_values contiene todos los diversos bits y piezas que dichos procedimientos del sistema necesitan, en una tabla SQL, para producir los diversos informes. El spt significa procedimiento del sistema; spt tablas de medios para los procedimientos del sistema; y por supuesto values es el contenido.

Tablas de consulta

¿Cuál es el (significado de) Tipo ='P'

La gente suele describir spt_values como "desnormalizado", pero ese es el término incorrecto. El término correcto es doblado , o empaquetado . Son aproximadamente 26 tablas de búsqueda lógicas, cada una hermosamente normalizada, plegadas en una tabla física, con un Type columna para diferenciar las tablas lógicas.

Ahora, en una base de datos normal, eso sería un gran error (solo mire las respuestas para "una tabla de búsqueda o muchas"). Pero en un catálogo de servidores, es deseable, reemplaza 26 tablas físicas.

  • "L" significa LockType Lookup; "V" significa Búsqueda de tipo de dispositivo (V es la abreviatura de Dispositivo en todo el servidor); etc. El tipo "P2" contiene ordinales bit a bit, para la expansión de bits que se empaquetan en un INT.

  • Se requiere un conjunto de números consecutivos dentro de límites conocidos, que está disponible en forma de una tabla SQL, para realizar una Proyección, lo que tienen que hacer muchos de los procedimientos del sistema. Tipo "P" es una lista de números consecutivos entre 0 y 2047.

  • El término Proyección se utiliza aquí como el significado técnicamente preciso, el sentido lógico natural, no el significado del álgebra relacional, que no es natural.

Por lo tanto, solo hay un propósito para spt_values, para contener 26 tablas de referencia plegadas, separadas de otro modo, y una tabla de proyección.

Expansión

El uso ordinario de spt_values entonces, es como una Búsqueda ordinaria o Referencia o ENUM mesa. Primero, los valores de búsqueda:

    SELECT *                    -- list Genders
        FROM Gender 

Se usa de la misma manera que Person tiene un GenderCode que necesita expandirse (muy expandido, en estos días raros):

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

P.ej. sp_lock produce un informe de bloqueos activos, que muestra los tipos de bloqueo como cadenas nombres . Pero master..syslocks contiene tipos de bloqueo como números , no contiene esos nombres; y si lo hiciera, ¡sería una tabla mal desnormalizada! Si ejecuta la consulta (código Sybase ASE, tendrá que convertir):

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

notará 66 LockType números y nombres en la tabla de búsqueda. Eso permite sp_lock para ejecutar código simple como Persona::Género arriba:

    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

Proyección

¿Cuál es el (significado de) Tipo ='P'?

¿Qué es Projection y cómo se usa?

Digamos, por ejemplo, que en lugar de los bloqueos activos producidos por la consulta anterior, desea una lista de todos 66 LockTypes, que muestran el número de bloqueos activos (o nulos). No necesitas un cursor, o un WHILE círculo. Podríamos Proyectar la tabla de búsqueda LockType, hasta el recuento de bloqueos activos:

    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"

Hay varios métodos, ese es solo uno. Otro método es utilizar una tabla derivada en lugar de la subconsulta. Pero aún necesita la Proyección.

Eso es típicamente lo que spt_values se usa para Expansión o Proyección. Ahora que sabes que está ahí, también puedes usarlo. Es seguro (en el master base de datos) y utilizada por prácticamente todos los procedimientos del sistema, lo que significa que los procedimientos del sistema no pueden ejecutarse sin ella.

¿para dividir una columna?

Ah, no entiende el código "Dividir una columna CSV en varias filas".

  • Olvídate de spt_values por un momento y vuelva a examinar ese código. Solo necesita una lista de números consecutivos, de modo que pueda recorrer la lista de valores en la columna CSV, byte por byte. El código se activa solo para cada byte que es una coma o final de cadena.

  • ¿Dónde obtener un conjunto de números consecutivos en forma de tabla SQL, en lugar de CREAR uno desde cero e INSERTARLO? Por qué, master..spt_values por supuesto. Si sabes que está ahí.

  • (Puede aprender un poco sobre el funcionamiento interno de ASE o SQL Server, simplemente leyendo el código de los procedimientos almacenados del sistema).

  • Tenga en cuenta que cualquier campo CSV en una columna es un error de normalización grave, rompe 2NF (contiene valores repetidos) y 1NF (no atómico). Tenga en cuenta que no está empaquetado ni doblado, es un grupo repetitivo, no está normalizado. Una de las muchas consecuencias negativas de un error tan grave es que, en lugar de usar SQL simple para navegar por el grupo repetitivo como filas, se debe usar un código complejo para determinar y extraer el contenido del campo CSV no normalizado. Aquí spt_values P proporciona un vector para ese código complejo, haciéndolo más fácil.

¿Cuál es el beneficio de esto?

Creo que he respondido eso. Si no lo tuviera, cada procedimiento del sistema que requiera una lista de Números tendría que CREAR una tabla temporal; e INSERTAR las filas en él; antes de ejecutar su código. Por supuesto, al no tener que realizar esos pasos, los trámites del sistema son mucho más rápidos.

Ahora, cuando necesite realizar una Proyección, por ej. fechas de calendario en el futuro, o lo que sea, puede usar spt_values , en lugar de tener que crear su propia tabla temporal cada vez (o crear su propia tabla permanente privada y mantenerla).