Estándares de Programación SQL
Estándares de Programación SQL
Programación SQL
Estándares de Programación de SQL
Tabla de Contenido
Referencias
GYC_CON_EstandaresNomenclaturaSQL.doc
Para modificar un Objeto existente se debe utilizar la instrucción alter <Tipo Objeto> <Objeto> para
asegurar que se está modificando un objeto existente.
Utilizar set nocount on al inicio un grupo o “batch” de instrucciones, “stored procedures”, “triggers” o
“funciones”. Estas instrucciones eliminarán los mensajes de número de registros afectados posteriores a la
ejecución de instrucciones como: select, insert, update, delete aumentando el desempeño de los “stored
procedures” al disminuir la cantidad de información transmitida por la red.
Eliminar las sentencias de prueba que se utilizan durante el desarrollo o modificación de objetos (sentencias
select, print). Ya que generan resultados (resultsets) y tráfico de red innecesarios.
Ejemplo:
-- Incorrecto
PRINT @Endoso
SELECT @Endoso
Los parámetros y las variables que se declaren dentro de los objetos deberán ser del mismo tipo de dato y
longitud del campo al cual hacen referencia, esto para evitar errores de desbordamiento.
Evitar el uso de ciclos y cursores, abordar los desarrollos utilizando teoría de conjuntos y no hacerlo registro
a registro, ya que el motor de base de datos esta optimizado para trabajar con conjuntos de registros,
apoyarse de las funciones diseñadas para tal fin, como son COMMON TABLE EXPRESSIONS (CTE),
USER DEFINED FUNCTIONS (UDF), APPLY. Son excepcionales los casos donde no se puede evitar el
uso de ciclos, tales casos deberán evaluarse por el área de arquitectura de datos
Para el manejo de información en formato XML dentro de los objetos de base de datos se debe utilizar
XQuery en lugar de OPENXML, ya que el uso de OPENXML utiliza demasiados recursos de memoria para
su ejecución al separar 1/8 parte de la memoria del servidor solamente para dicho proceso,
independientemente del tamaño del documento XML.
Ejemplo:
-- Incorrecto
-- Correcto
Creación Tablas
En la creación de tablas físicas es necesario que se especifique una llave primaria o índice único. Para
proteger la integridad de datos y optimización en el acceso a estos.
Tanto en la creación de tablas físicas como en las temporales se deberá especificar si los campos
contenidos en estas permitirán valores nulos o no.
No se debe de especificar el COLLATION de los campos, ya que se debe de tomar el que este definido por
defecto en la Base de Datos.
Se debe crear un índice agrupado (CLUSTERED), para asegurar que las tablas crezcan con el orden
definido por dicho índice y los índices no agrupados (NONCLUSTERED) proporcionen un mejor desempeño
al hacer referencia hacia el índice agrupado.
Se debe evitar la creación de columnas que almacenen descripciones de campos que existan en otras
tablas y los cuales se pueden obtener a través de llaves foráneas.(por ejemplo, descripciones de
catálogos), ya que con esto se incrementa el espacio de almacenamiento innecesariamente y va en contra
de las reglas de normalización.
Se deben crear llaves foráneas cuando exista relación entre dos o más tablas a través de un campo a fin de
garantizar la integridad referencial y la homogeneidad en cuanto al tipo y longitud de los campos.
Campo FechaUltimaModificacion
Es necesario que toda tabla maneje el campo FechaUltimaModificacion y un trigger que mantenga actualizado
este campo en altas y actualizaciones, ya que los procesos de DWH por medio de este campo mantienen
actualizadas las BDs requeridas para el análisis de la información
Nombre: FechaUltimaModificacion
Tipo: Datetime
Excepciones:
Las tablas que quedan exentas a este campo son aquellas que por la naturaleza del proceso en que se
encuentren se estén depurando constantemente, o aquellas que se utilicen solo para manejo de información de
forma masiva.
Comentarios en Procesos
Se debe de comentarizar tanto las creaciones de nuevos sps, triggers y vistas, como los cambios que
sufren estos, para tener una referencia de de la historia del objeto.
Para la modificación de objetos existentes se necesita la siguiente información y deberá ir enseguida de los
comentarios del ultimo cambio de existir este o comentarios de la creación del objeto.
Ejemplo de Sp:
Se debe de Comentarizar cada parte del flujo de los sps que realicen más de una instrucción, para darle
legibilidad al código. Ejem:
.
.
-- Obtener los Recibos emitidos en un periodo de Fechas determinado.
insert #tmpRecibos(ClaveId, PolizaId, IncisoId, EndosoId, Recibo)
select ClaveId, PolizaId, IncisoId, EndosoId, Recibo
from Recibo
where EmisionFecha >= @FechaDesde and EmisionFecha < @FechaHasta
Al insertar datos en una tabla se deben de especificar que campos son los que se van a manejar en la
inserción, para que en futuros cambios a la estructura de esta no afecte los procesos actuales.
Ejem:
Insert Tabla (Campo1, Campo2, Campo3)
Select Campo1, Campo2, Campo3
From Tabla2
No se deben de utilizar los números de las columnas en la cláusula de ORDER BY, esto puede causar
confusiones y errores si la estructura de la base de datos cambia. En su lugar siempre se debe usar el
nombre de la columna.
Ejemplo:
-- Incorrecto
select PedidoID, FechaPedido
from Pedidos
order by 2
-- Correcto
select PedidoID, FechaPedido
from Pedidos
order by FechaPedido
Utiliza el estándar ANSI para las sentencias básicas. Con el estándar ANSI la cláusula WHERE se utiliza
solamente para el filtrado de datos a diferencia de la notación antigua donde la cláusula de WHERE se
utiliza tanto para el filtrado de datos como para el manejo de las condiciones del JOIN.
Ejemplo:
-- Incorrecto
Select [Link], [Link]
From Publicaciones P, Autores A, PublicacionesAutores PA
Where [Link] = [Link] and [Link] = [Link]
and [Link] LIKE '%Computadora%'
-- Correcto
select [Link], [Link]
from Autores A
inner join PublicacionesAutores PA
on [Link] = [Link]
inner join Publicaciones P
on [Link] = [Link]
En lugar de los caracteres *= y =*, se deben utilizar LEFT y RIGTH joins que son el estándar de ANSI. Los
caracteres comodín para expresar este tipo de joins no serán soportada en las siguientes versiones de SQL.
No se deben utilizar directamente estatutos de SELECT, INSERT, UPDATE o DELETE desde las
aplicaciones. En vez de esto se deben crear “stored procedures” y darle permiso a las aplicaciones para
ejecutarlos. Esto permite un acceso a los datos más limpio así como mantener la consistencia a través de
los diferentes módulos de la aplicación y centralizar la lógica de negocios en la base de datos.
En caso de manejar diferentes “owners” de los objetos de base de datos, agregar el “owner” del objeto
como prefijo, esto aumenta la legibilidad del código.
Ejemplo:
Cuando se realice un query que involucre dos o mas tablas, se deberá especificar en cada campo el alias
de la tabla a la que pertenece.
Ejemplo:
--Correcto
Select t1.Campo1, t2.Campo2
From Tabla1 t1 inner join Propietario.Tabla2 t2
On [Link] = [Link]
No se debe utilizar la clausula ORDER BY en la inserción de registros, ya que el motor de base de datos no
garantiza que los registros se inserten en el orden indicado.
No se deben manipular las columnas que están contenidas en la sección posterior al WHERE con (ISNULL,
DATEPART, DATEDIFF, etc), ya que este tipo de manipulaciones evita que se utilicen los índices definidos
para esos campos.
Ejemplo:
-- Incorrecto
--- Correcto
Se puede hacer el uso del “.[owner].” Comúnmente conocido como “..” en las sentencias básicas o
ejecución de SPs en los cuales intervenga una BD diferente a la actual, siempre y cuando la relación entre
estas BD se encuentre especificada en la lista de relaciones de BDs abajo mencionada.
Para obtener información de una relación que no se encuentre en la lista de relaciones de BDs se debe de
hacer mediante los Linked Servers haciendo uso de vistas o SPs
Ejemplos:
o Obtener información de la vista vwPoliza de la BD local de Auto
BD Local BD Remota
Cartera Auto
Diverso Auto
Auto Caja
Diverso Caja
Cartera Caja
Siniestro Caja
Seguimiento Caja
Contacto Caja
Reaseguro Caja
Auto Cartera
Diverso Cartera
OficinaVirtual Corporativo
Auto Diverso
Cartera Diverso
Reaseguro Diverso
Corporativo OficinaVirtual
Diverso Reaseguro
Auto Seguro
Diverso Seguro
Cartera Seguro
Siniestro Seguro
Caja Seguro
Seguimiento Seguro
Contacto Seguro
Reaseguro Seguro
Auto Siniestro
Diverso Siniestro
Cartera Siniestro
Reaseguro Siniestro
Seguimiento Siniestro
Flujos de Procesos
No utilizar la instrucción GOTO. Este tipo de instrucciones puede hacer al código menos legible.
Tablas Temporales
La creación de tablas temporales al igual que la declaración de variables se deben de hacer al principio del
sp, ya que al estar dispersas en el sp puede provocar la recompilación del objeto.
Al terminar de usar una tabla temporal se deberá liberar los recursos que esta utilice mediante la sentencia
drop table #Tabla, ya que de no hacerlo los recursos no se liberan hasta cerrar la cesión.
Seguridad
Las tablas deberán ser accesadas por medio de SPs o Vistas, no se deberá dar acceso directamente a
la tabla.
No se deberá dar permisos al rol PUBLIC de SQL para el acceso a los objetos, las aplicaciones y/o
procesos deberán estar asociadas a roles de Base de Datos generados para ello.
Las cuentas genéricas de aplicaciones por ningún motivo deberán ser propietarias de la base de datos,
así como tampoco administradoras de SQL
Se deben otorgar permisos vía objetos (esquemas ó cada objeto) en LAS TABLAS no se debe otorgar
ningún permiso ya que debemos accederlas vía Stored Procedures, Vistas, Triggers.
Deben existir roles en SQL server por BD y debemos asociar la o las cuentas genéricas a estos
Por BD deben existir roles y cuentas para administrador, consultas, y registro de información con menor
privilegio a un administrador
Las cuentas genéricas de procesos por ningún motivo deberán ser administradoras de SQL
o LMGR
Cuenta para ejecutar reportes nocturnos (Procesos SQT, SQR, Reportes usando Scripts SQL)
o DTSMGR
Cuenta para las conexiones a las BDs de SQL que son accesadas por los procesos operativos
o OPERADWH
Cuenta para las conexiones a las BDs de SQL que son accesadas por los procesos ETL de BI
Linked Servers
Para ejecutar procesos que hagan uso de linked servers se tendrá que hacer mediante la cuenta
genérica que utilice la aplicación, reporte procesos operativo.
Importante: El uso de las cuentas administradoras o cuentas que no sean las que utiliza el proceso en
producción, generarán riesgos y/o re trabajos por no contar con los privilegios requeridos para su
ejecución.
No se debe de hacer uso de manera directa a las tablas mediante Linked Servers, Revisar el apartado
“Acceso a información de otras BDs” del documento de estándares de programación de SQL
(GYC_CON_EstandaresProgramacionSQL.doc), ya que requerirán que se asignen permisos
directamente a las tablas.
Replicación
Objetos a Publicar
Es responsabilidad del equipo responsable del cambio el identificar y revisar con el negocio que objetos
deberán ser replicados o no dada su importancia en el proceso afectado
Tablas
Las tablas que requieran ser replicadas por el mecanismo de replicación de SQL deberán contar con una llave
primaria.
Las tablas a replicar son aquellas que mantendrán historia; aquellas que se requieran estar depurando por la
naturaleza del proceso (tablas temporales o de paso en algún proceso) pero que se requieran para realizar
alguna función en el ambiente de replicación solo se replicará la estructura.
Triggers
Para la liberación de triggers nuevos o cambios en ellos se tiene que especificar la cláusula Not For
Replication como se muestra a continuación:
Create Trigger [Link]
On [Link]
For Update
Not For Replication
As ...
Esto con la finalidad de que no se ejecute cuando se está transfiriendo la información por medio de la
replicación
Una vez con la estructura de la tabla establecida y/o los SPs, triggers o vistas que se requieran replicar, se
deberán poner en contacto con el responsable del ambiente de replicación para que estos objetos sean
contemplados por el proceso de replicación a utilizar.
Todas las sentencias para publicar los objetos se manejarán en un archivo adicional por base de datos
afectada, estas sentencias serán ejecutadas en la Base de Datos OPERACION en el servidor de datos donde
se encuentran los objetos que fueron liberados
A continuación se detallan las funciones con las que se cuenta para publicar objetos en el ambiente de
replicación
Tablas
Procedimientos almacenados
Funciones de usuario
Vistas
Sintaxis
Argumentos
[DBName = ] ‘Database’
[@SchemaName = ] ‘Schema’
Es el nombre del esquema al que pertenece el objeto a registrar. Schema es de tipo nvarchar(256) sin
valor de default.
[@ObjetcName = ] ‘Object’
Es el nombre del objeto que se desea registrar. Object es de tipo nvarchar(256) sin valor de default.
[@ReplType = ] Type
Es el tipo de replicación a configurar para el objeto que se va a registrar. Type es de tipo tinyint sin valor
de default. Valores permitidos:
Valor Descripción
0 No se replica ni estructura ni datos.
Para Procedimientos Almacenados, Funciones y Vistas solo se puede utilizar el valor 1. Para Tablas los valores
0, 1 y 2.
Notas
0 (Correcto) ó 1 (Error).
Ejemplo
Sintaxis
Argumentos
[DBName = ] ‘Database’
[@SchemaName = ] ‘Schema’
Es el nombre del esquema al que pertenece el objeto a modificar. Schema es de tipo nvarchar(256) sin
valor de default.
[@ObjetcName = ] ‘Object’
Es el nombre del objeto que se desea modificar. Object es de tipo nvarchar(256) sin valor de default.
[@NewReplType = ] Type
Es el nuevo tipo de replicación a configurar para el objeto. Type es de tipo tinyint sin valor de default.
Valores permitidos:
Valor Descripción
0 No se replica.
1 Se replica a través de Replica Transaccional de SQL Server.
Notas:
0 (Correcto) ó 1 (Error).
Ejemplo
Sintaxis
Argumentos
[DBName = ] ‘Database’
Es el nombre de la base de datos a la que pertenece el objeto que se desea quitar. Database es de tipo
nvarchar(256) sin valor de default.
[@SchemaName = ] ‘Schema’
Es el nombre del esquema al que pertenece el objeto que se desea quitar. Schema es de tipo
nvarchar(256) sin valor de default.
[@ObjetcName = ] ‘Object’
Es el nombre del objeto que se desea quitar. Object es de tipo nvarchar(256) sin valor de default.
Notas
El objeto debe existir en su correspondiente base de datos y esquema, así como pertenecer a una de
las publicaciones de Replica Transaccional de SQL Server.
El quitar un objeto de su publicación no requiere la generación de snapshot.
0 (Correcto) ó 1 (Error).
Ejemplo
Agregar nuevamente a una publicación un objeto que anteriormente ya había sido publicado.
Este procedimiento almacenado permite agregar nuevamente a una publicación de Replica Transaccional de
SQL Server un objeto que haya sido removido a través del procedimiento almacenado:
[Link].
Sintaxis
Argumentos
[DBName = ] ‘Database’
Es el nombre de la base de datos a la que pertenece el objeto que se desea volver a publicar. Database
es de tipo nvarchar(256) sin valor de default.
[@SchemaName = ] ‘Schema’
Es el nombre del esquema al que pertenece el objeto que se desea volver a publicar. Schema es de
tipo nvarchar(256) sin valor de default.
[@ObjetcName = ] ‘Object’
Es el nombre del objeto que se desea volver a publicar. Object es de tipo nvarchar(256) sin valor de
default.
Notas
0 (Correcto) ó 1 (Error).
Ejemplo
Objetos encriptados
Los objetos que requieran ser encriptados no se podrán replicar de manera automática, estos objetos deberán
de notificarse al responsable del ambiente de replicación, ya que se tendrán que liberar de manera manual en
ambos ambientes.
Importante:
En el caso de hacer uso de IDENTITYs la función para capturar el valor utilizado en un registros es
SCOPE_IDENTITY(), ya que el uso de @@Identity puede devolver datos incorrectos.
Recomendaciones
Evitar el uso de variables tipo tabla en procesos cuando estas almacenen una cantidad considerable de
información y se realicen joins con otras tablas, ya que el performance se ve degradado de manera
considerable.
Para contemplar el uso de estos objetos se debe de realizar pruebas de desempeño exhaustivas para
evitar problemas de performance en las aplicaciones.
Evitar el uso del hint WITH RECOMPILE en la creación de Stored Procedures, ya que dicho hint evita
que el motor de base de datos reutilice los planes de ejecución existentes para dicha consulta, lo cual
hace que se afecte el desempeño de objeto.
Evitar el uso del query hint WITH INDEX, ya que evita que el motor de base de datos tome la mejor
opción de índice (inclusive puede no tomar en cuenta los índices) de acuerdo a las estadísticas,
distribución, cardinalidad, etc, de los datos.