Estándares de formato SQL – combinaciones, listas, estructura, operaciones

La primera parte de la serie – Estándares de formato SQL – Mayúsculas y minúsculas, Sangría, Comentarios, Paréntesis, explica la importancia de tener un SQL limpio. En resumen, descifrar el código de alguien más consume tiempo. Un código SQL limpio y ordenado puede ser rápido de leer; la revisión de SQL y la resolución de problemas más eficiente; los esfuerzos de desarrollo combinados son más efectivos; pasar proyectos de un equipo a otro es más fácil que con un SQL escrito inconsistentemente.

Ya que no hay estilos o estándares para formatear SQL, es trabajo del equipo crear su propio conjunto de estándares de formato. Aquí hay algunas recomendaciones para formatear operaciones de combinaciones, listas de valor, estructura de código, aritmética, comparación y lógica.

Combinaciones

Como las combinaciones SQL añaden complejidad, el código legible aquí es esencial. Esta complejidad es traída por el número de parámetros que pueden ser formateados en cada JOIN: la palabra clave JOIN, la palabra clave ON, la primera tabla en la sentencia JOIN, un objeto combinado. Mientras que el número de tablas combinadas se incrementa, así también lo hace la importancia de formatear SQL apropiadamente.

Los dilemas más comunes para los desarrolladores son: ¿Deberían las palabras reservadas JOIN ser colocadas en nuevas líneas? ¿Debería cada cláusula en un JOIN ser colocada en una nueva línea? ¿Cuánto usar de sangría en la palabra ON si se pone en una nueva línea?

SQL Formatting options - Joins

Depende del equipo decidir. Los siguientes ejemplos pueden ayudar en tomar una decisión:

Estilo 1 – La palabra reservada JOIN se coloca en una nueva línea. La palabra ON está también en una nueva línea, con sangría de 0 espacios/alineada con la palabra JOIN:

SELECT e.BusinessEntityID , 
       p.Title , 
       pp.PhoneNumber , 
       pnt.Name AS PhoneNumberType , 
       ea.EmailAddress , 
       a.AddressLine1 , 
       sp.Name AS StateProvinceName , 
       cr.Name AS CountryRegionName
  FROM
       HumanResources.Employee e
       INNER JOIN Person.Person p
       ON p.BusinessEntityID
          = 
          e.BusinessEntityID
       INNER JOIN Person.BusinessEntityAddress bea
       ON bea.BusinessEntityID
          = 
          e.BusinessEntityID
       INNER JOIN Person.Address a
       ON a.AddressID
          = 
          bea.AddressID
       INNER JOIN Person.StateProvince sp
       ON sp.StateProvinceID
          = 
          a.StateProvinceID
       INNER JOIN Person.CountryRegion cr
       ON cr.CountryRegionCode
          = 
          sp.CountryRegionCode
       LEFT OUTER JOIN Person.PersonPhone pp
       ON pp.BusinessEntityID
          = 
          p.BusinessEntityID
       LEFT OUTER JOIN Person.PhoneNumberType pnt
       ON pp.PhoneNumberTypeID
          = 
          pnt.PhoneNumberTypeID
       LEFT OUTER JOIN Person.EmailAddress ea
       ON p.BusinessEntityID
          = 
          ea.BusinessEntityID;

Estilo 2 – La palabra reservada JOIN es colocada en una nueva línea. La palabra ON no es movida a una nueva línea:

SELECT e.BusinessEntityID , 
       p.Title , 
       pp.PhoneNumber , 
       pnt.Name AS PhoneNumberType , 
       ea.EmailAddress , 
       a.AddressLine1 , 
       sp.Name AS StateProvinceName , 
       cr.Name AS CountryRegionName
  FROM
       HumanResources.Employee e
       INNER JOIN Person.Person p ON p.BusinessEntityID
                                     = 
                                     e.BusinessEntityID
       INNER JOIN Person.BusinessEntityAddress bea ON bea.BusinessEntityID
                                                      = 
                                                      e.BusinessEntityID
       INNER JOIN Person.Address a ON a.AddressID
                                      = 
                                      bea.AddressID
       INNER JOIN Person.StateProvince sp ON sp.StateProvinceID
                                             = 
                                             a.StateProvinceID
       INNER JOIN Person.CountryRegion cr ON cr.CountryRegionCode
                                             = 
                                             sp.CountryRegionCode
       LEFT OUTER JOIN Person.PersonPhone pp ON pp.BusinessEntityID
                                                = 
                                                p.BusinessEntityID
       LEFT OUTER JOIN Person.PhoneNumberType pnt ON pp.PhoneNumberTypeID
                                                     = 
                                                     pnt.PhoneNumberTypeID
       LEFT OUTER JOIN Person.EmailAddress ea ON p.BusinessEntityID
                                                 = 
                                                 ea.BusinessEntityID;

Estilo 3 – La palabra reservada JOIN no está en una nueva línea, la palabra ON está en una nueva línea alineada con la palabra JOIN:

SELECT e.BusinessEntityID , 
       p.Title , 
       pp.PhoneNumber , 
       pnt.Name AS PhoneNumberType , 
       ea.EmailAddress , 
       a.AddressLine1 , 
       sp.Name AS StateProvinceName , 
       cr.Name AS CountryRegionName
  FROM
       HumanResources.Employee e INNER JOIN Person.Person p
                                 ON p.BusinessEntityID
                                    = 
                                    e.BusinessEntityID
                                 INNER JOIN Person.BusinessEntityAddress bea
                                 ON bea.BusinessEntityID
                                    = 
                                    e.BusinessEntityID
                                 INNER JOIN Person.Address a
                                 ON a.AddressID
                                    = 
                                    bea.AddressID
                                 INNER JOIN Person.StateProvince sp
                                 ON sp.StateProvinceID
                                    = 
                                    a.StateProvinceID
                                 INNER JOIN Person.CountryRegion cr
                                 ON cr.CountryRegionCode
                                    = 
                                    sp.CountryRegionCode
                                 LEFT OUTER JOIN Person.PersonPhone pp
                                 ON pp.BusinessEntityID
                                    = 
                                    p.BusinessEntityID
                                 LEFT OUTER JOIN Person.PhoneNumberType pnt
                                 ON pp.PhoneNumberTypeID
                                    = 
                                    pnt.PhoneNumberTypeID
                                 LEFT OUTER JOIN Person.EmailAddress ea
                                 ON p.BusinessEntityID
                                    = 
                                    ea.BusinessEntityID;

Listas de valores

Un constructor con valores de tabla es usado para especificar un conjunto de expresiones de valores de fila que serán insertados en una tabla, usando una sola sentencia DML. Puede ser usado en la cláusula VALUES de la sentencia INSERT INTO, la cláusula USING < tabal fuente > de la sentencia MERGE, y en la definición de una tabla derivada en la cláusula FROM.

Las listas de valores en un constructor con valores de tabla, en cualquiera de los casos anteriores, pueden ser formateadas usando el mismo conjunto de reglas en la pestaña Lists debajo de la sub pestaña Values.

Los parámetros que pueden ser formateados son: la palabra VALUES, filas enteras y valores de fila:

SQL Formatting options - Value lists

El conjunto de formatos en la sub pestaña Values no es aplicado a la lista de columnas de tabla en la cláusula INSERT INTO. Esta es formateada usando el conjunto de reglas establecido en la pestaña Lists debajo de la sub pestaña Columns de la sección Column lists:

SQL Formatting options - Data statements tab

El conjunto de opciones de formato de paréntesis en la pestaña Lists debajo de Valueses aplicado a los paréntesis de las listas de valores.

Estilo 1 – La lista de valores es colocada en una línea, pero todos los valores están en la misma línea:

INSERT INTO Production.UnitMeasure(
           	    Name , 
            	    UnitMeasureCode , 
            	    ModifiedDate )
VALUES
               (N'FT2', N'Square Feet ', '20080923'), (N'Y', N'Yards', '20080923'), (N'Y3', 'Cubic Yards', '20080923');
GO

Estilo 2 – Cada valor de fila está en una nueva línea, con una coma colocada al final de cada línea:

INSERT INTO Production.UnitMeasure(
           	   Name , 
            	   UnitMeasureCode , 
            	   ModifiedDate )
VALUES
              ( N'FT2' , N'Square Feet ' , '20080923' ) , 
              ( N'Y' , N'Yards' , '20080923' ) , 
              ( N'Y3' , 'Cubic Yards' , '20080923' );
GO

Estilo 3 – Cada valor es colocado en una nueva línea:

INSERT INTO Production.UnitMeasure(
            Name , 
            UnitMeasureCode , 
            ModifiedDate )
VALUES
       ( N'FT2'
       , N'Square Feet '
       , '20080923' ) , 
       ( N'Y'
       , N'Yards'
       , '20080923' ) , 
       ( N'Y3'
       , 'Cubic Yards'
       , '20080923' );
GO

Estructura

Crear saltos de línea, el espaciado y el alineamiento son los desafíos más grandes en el formateo de SQL. Ellos contribuyen significativamente a la legibilidad de SQL, así que asegúrese de que los estándares de formato de código SQL están apropiadamente establecidos para ellos.

Aquí están algunas guías básicas que pueden ser usadas cuando se establezcan los estándares de formato SQL para las cláusulas SELECT, FROM, JOIN, WHERE, GROUP BY y ORDER BY:

  • Coloque cada palabra reservada en una nueva línea
  • Coloque los argumentos en una nueva línea
  • Use sangría en las líneas de acuerdo a la palabra reservada precedente
  • Coloque todas las sentencias SELECT en una nueva línea
  • Alinee una sentencia SELECT con una palabra reservada precedente, o aplique una sangría de 4 espacios
  • Coloque la palabra reservada FROM ya sea en una nueva línea o en la misma línea con las columnas seleccionadas
  • Ajuste las líneas de más de 80 caracteres
  • Ajuste las sentencias SELECT con más de 30 caracteres

Un inconveniente de este enfoque son los excesivos espacios blancos y mucho desplazamiento a través del código SQL.

SQL Formatting options - Data statements

Estilo 1 –Todos los elementos de la lista de columnas están en la misma línea, la palabra reservada FROM tiene una sangría de 2 espacios, la sentencia SELECT anidada es colocada en una nueva línea alineada con la palabra reservada precedente:

SELECT Col_name , data_type , audit_log_data_id
  FROM dbo.AUDIT_LOG_DATA
  WHERE AUDIT_LOG_TRANSACTION_ID IN( 
        SELECT AUDIT_LOG_TRANSACTION_ID
          FROM dbo.AUDIT_LOG_TRANSACTIONS
          WHERE TABLE_NAME LIKE 'ProductPhoto' );

Estilo 2 – Todos los elementos de la lista de columnas están en la misma línea, la palabra reservada FROM tiene una sangría de 2 espacios, la sentencia anidada SELECT es colocada en una nueva línea después del último carácter en la línea precedente:

SELECT Col_name , data_type , audit_log_data_id
  FROM dbo.AUDIT_LOG_DATA
  WHERE AUDIT_LOG_TRANSACTION_ID IN( 
                                     SELECT AUDIT_LOG_TRANSACTION_ID
                                       FROM dbo.AUDIT_LOG_TRANSACTIONS
                                       WHERE TABLE_NAME LIKE 'ProductPhoto' );

Estilo 3 – las palabras reservadas FROM y WHERE no son movidos a una nueva línea, la sentencia SELECT es colocada en una nueva línea con una sangría de 4 espacios:

SELECT Col_name , data_type , audit_log_data_id
  FROM dbo.AUDIT_LOG_DATA WHERE AUDIT_LOG_TRANSACTION_ID IN(
    SELECT AUDIT_LOG_TRANSACTION_ID
      FROM dbo.AUDIT_LOG_TRANSACTIONS WHERE TABLE_NAME LIKE 'ProductPhoto' );

Operaciones de aritmética, comparación y lógica

La legibilidad de SQL también puede ser mejorada si las operaciones de aritmética, comparación y lógica son formateadas. Sea cuidadoso con el salto de línea para operaciones y con extenderlas a través de múltiples líneas, ya que puede convertir un código SQL de 2 líneas en uno de 20 líneas, como se muestra en uno de los ejemplos a continuación:

SQL Formatting options - Expressions

Estilo 1 – Las operaciones no son movidas a nuevas líneas ni son extendidas a través de múltiples líneas:

SELECT employee , oldsalary , newsalary
  FROM salary
  WHERE oldsalary <= AVG( oldsalary ) AND oldsalary + @COLI * oldsalary < 
AVG( NewSalary ) OR @COLI + 10 - (AVG( oldsalary ) + 125) / 5 < 1000;

Estilo 2 – Todas las operaciones son movidas a nuevas líneas y son expandidas a través de múltiples líneas:

SELECT employee , oldsalary , newsalary
  FROM salary
  WHERE
       oldsalary
       <= 
       AVG( oldsalary )
   AND
       oldsalary
     + @COLI
     * oldsalary
       < 
       AVG( NewSalary )
    OR
       @COLI
     + 10
     - (
       AVG( oldsalary )
     + 125)
     / 5
       < 
       1000;

Estilo 3 – Todas las operaciones, excepto las aritméticas, son movidas a nuevas líneas y son expandidas a través de múltiples líneas:

SELECT employee , oldsalary , newsalary
  FROM salary
  WHERE
       oldsalary
       <= 
       AVG( oldsalary )
   AND
       oldsalary + @COLI * oldsalary
       < 
       AVG( NewSalary )
    OR
       @COLI + 10 - (AVG( oldsalary ) + 125) / 5
       < 
       1000;

Una vez que las reglas están definidas, lo siguiente es encontrar una manera fácil de implementarlas. Aplicar todas las reglas manualmente es un proceso que consume tiempo donde es muy posible que ocurran errores.

Aquí es donde nuestro formateador de código SQL puede ayudar.

ApexSQL Refactor es un complemente de SQL Server Management Studio y Visual Studio, el cual formatea y refactoriza SQL utilizando cerca de 160 opciones de formato. Puede ser usado para distribuir y reforzar estándares de formato SQL y reglas entre miembros del equipo

Para establecer las reglas de formato para SQL:

  1. En SQL Server Management Studio o Visual Studio, haga clic en ApexSQL Refactor desde el menú de ApexSQL.
  2. Seleccione Options desde el menú ApexSQL Refactor:

    ApexSQL Refactor SSMS menu

  3. Establezca las opciones específicas como se describen en este artículo.
  4. Observe la vista previa del efecto de la opción en la consulta actual o un ejemplo integrado:

    ApexSQL Refactor formatting options

  5. En SQL Server Management Studio o Visual Studio, vaya al menú de ApexSQL, seleccione ApexSQL Refactor, seleccione la opción Format SQL y elija uno de los perfiles de formato para aplicar a SQL en la pestaña Query Editor.

Distribuir un perfil de formato SQL de ApexSQL Refactor a todos los miembros del equipo también es fácil:

  1. En la ventana Options haga clic en el botón Export para grabar las reglas de formato a un archivo XML:

    ApexSQL Refactor general formatting options

  2. Especifique el nombre del archivo y su localización.
  3. Copie el archivo XML a la máquina de un compañero de equipo.
  4. En la ventana Options, haga clic en la opción Import.
  5. Navegue al archivo XML.

Las guías claras y la implementación automática de las reglas de formato aseguran que todos los miembros del equipo, y cualquiera que hereda el código, puede leerlo fácilmente. Codifique sabiamente y no pierda tiempo descifrando un SQL confuso. Use ApexSQL Refactor para automáticamente implementar todos los estándares de formato SQL.

Traductor: Daniel Calbimonte

octubre 16, 2016