Create table condicionado usando el diccionario de datos de Sql Server 2008

En ciertas ocasiones necesitamos comprobar la existencia de una tabla en un script o tarea programada para poder registrar eventos de erro, primeras ejecuciones etc... Pongamos un ejemplo, un paquete de integration services que solemos distribuir o ejecutar allà a donde vamos y que deja trazas en un tabla personalizada que no es la predefinida para los logs de carga. Podríamos incluir siempre una Tarea de ejecución sql o de script, que se ejecute bien o mal, sea la primera en ejecutarse en el paquete y luego continue. Siendo puristas esto solo no es del todo “prolijo”:

CREATE TABLE LogsEtl
(Ejecucion int PRIMARY KEY,
Paquete varchar(50),
Fecha datetime);
GO

En la primera ejecución la salida será correcta pero en posteriores fallará en la creación de la tabla. Esto lo podemos suplir consultando la vista sys.Objects, donde existe un registro por cada objeto de la base de datos, y comprobar la existencia de la tabla antes de crearla. La visibilidad de los metadatos se limita a los elementos protegibles y que son propiedad del usuario o sobre los que el usuario tiene algún permiso. La estructura de la vista es la siguiente:

name                 (sysname)
object_id             (int)
principal_id            (int)
schema_id            (int)
parent_object_id        (int)
type                (char(2))
type_desc            (nvarchar(60))
create_date            (datetime)
modify_date            (datetime)
is_ms_shipped        (bit)
is_published            (bit)
is_schema_published    (bit)

Si cambiamos la sentencia anterior por un create table condicionado por una consulta sobre la vista buscando por el nombre de la tabla como parámetro de object_id(función que devuelve el identificador único de un objeto por su nombre) tendremos algo así:

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[LogsEtl]') AND TYPE = N'U')
CREATE TABLE LogsEtl
(Ejecucion int PRIMARY KEY,
Paquete varchar(50),
Fecha datetime);
GO

De esta manera lo estamos haciendo “prolijo” y la ejecución siempre será correcta (a no ser por la falta de permisos).
Realmente esto tiene otras aplicaciones porque podríamos hacer cualquier tipo de script condicionado por la existencia o no de objetos en la bbdd o modificación. Por ejemplo uno mismo podría hacer una consulta o script universal que actualizara/reconstruyera índices en base al tiempo que ha pasado desdela última modificación. Podríamos controlar a nivel de administración que esta “inventando” aquel usuario con permisos de más etc etc... en msdn hay algun ejemplo más.