SQL

Como obtener el valor default de una columna en SQL Server usando T-SQL

SQL Server

SQL Server

Hoy alguien de mi equipo de trabajo me preguntó como se podía comparar los valores de una columna para cada row contra el valor default de esa columna.

Después de probar un rato en el Management Studio, aprendí que se puede utilizar las vistas de INFORMATION_SCHEMA para obtener información de metadata sobre objetos en SQL Server.

Solo para aclarar…esto seguramente se puede hacer usando la tabla sysobjects de SQL Server, pero quería hacerlo de una manera más legible.

El query para obtener el valor default de una columna de alguna tabla es:


SELECT COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Vendedor'
AND COLUMN_NAME = 'CodigoPais'

Un dato muy importante es que estas vistas (INFORMATION_SCHEMA) se crearon para apegarse al estándar SQL-92, con el objetivo de proveer meta-datos sobre los objetos de la base de datos.

Me dió gusto el haber investigado otra alternativa a sysobjects, porque esta investigación me hizo darme cuenta que el realizar mis queries para obtener meta-data usando INFORMATION_SCHEMA en lugar de SYSOBJECTS hace que mis queries sean portables, en lugar de estar limitados a SQL Server solamente, o incluso considerando también el escenario en que Microsoft decidiera cambiar la estructura de SYSOBJECTS de alguna manera que afectara mis queries.

Hay varias vistas de INFORMATION_SCHEMA. Para este escenario solo usé la de Columns, pero hay más, por ejemplo:

  • CHECK_CONSTRAINTS
  • REFERENTIAL_CONSTRAINTS
  • COLUMN_DOMAIN_USAGE
  • ROUTINES
  • COLUMN_PRIVILEGES
  • ROUTINE_COLUMNS
  • COLUMNS
  • SCHEMATA
  • CONSTRAINT_COLUMN_USAGE
  • TABLE_CONSTRAINTS
  • CONSTRAINT_TABLE_USAGE
  • TABLE_PRIVILEGES
  • DOMAIN_CONSTRAINTS
  • TABLES
  • DOMAINS
  • VIEW_COLUMN_USAGE
  • KEY_COLUMN_USAGE
  • VIEW_TABLE_USAGE
  • PARAMETERS
  • VIEWS

Les dejo la siguiente liga a un artículo del SQL Server Development Center de Microsoft, donde explican más detalles de las vistas de INFORMATION_SCHEMA, y a otro artículo que da información general referente a estas.

INFORMATION_SCHEMA Views

INFORMATION_SCHEMA – A map to your database

Como cambiar el directorio default para respaldos de bases de datos en SQL Server 2005

Casi todos los días realizo un respaldo de la base de datos de una aplicación a la que le doy mantenimiento. La mayoría de la gente ya conoce el exageradamente sencillo proceso de dar click derecho sobre la base de datos que queremos respaldar, elegir la opción Tasks ->Backup, la cual nos presenta el siguiente diálogo.

Como cambiar el directorio default para respaldos de bases de datos en SQL Server 2005

Como cambiar el directorio default para respaldos de bases de datos en SQL Server 2005

Ahora, si solo mantuviéramos un archivo de respaldo, la ubicación y nombre del archivo default tal vez estarían bien. El problema, para mí, es que yo guardo cada archivo de respaldo histórico en una estructura de tipo

D:\Proyecto\DatabaseBackup\fechaCompleta.bak

Por lo cual, si en el dialogo selecciono la opción de Remove, y luego la opción de Add, el directorio default para el respaldo de la base de datos se reinicia al default, que es algo así como el siguiente (puede variar según la instalación que cada quien haya hecho)

C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data

En mi opinión es desesperante tener que elegir el directorio en el que quiero guardar mi respaldo cada vez que realizo uno. Intenté revisar las opciones disponibles en Tools -> Options y no encontré ningún setting para poder definir el directorio default a la hora de hacer un respaldo.

En algún lugar tenia que estar configurable ese setting, al menos para que el mismo SQL Server lo accesara, mi primer suposición fue la registry de Windows, y después de 5 minutos, Google confirmó.

Si abren la registry de Windows (Start -> Run -> regedit) y navegan hacia la llave

Para Windows 32 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer

Para Windows 64 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer

Ahi está la llave BackupDirectory, a la cual se le puede modificar el valor a lo que ustedes quieran. Después, al momento de realizar un nuevo backup, solamente hay que modificar el nombre del archivo (si acaso se desea) y listo, no se pierde más tiempo en navegar hasta el folder correcto cada vez que se hace un respaldo.

Espero les sirva.

Que significa sargeable en SQL

Al estar leyendo foros de SQL sobre maneras de optimizar queries, me tope con una sugerencia de un DBA experto en la cual le sugeria a otro DBA el hacer que su query fuera sargeable. Nunca antes habia escuchado el termino, y al parecer no es tan conocido.

Despues de leer un poco sobre el termino, me di cuenta que deberia ser conocimiento basico de SQL para cualquier desarrollador.

Que la clausula de WHERe de un Query de SQL sea Sargeable significa que contenga una constante contra la cual comparar directamente el valor del campo de una tabla y el beneficio de que sea sargeable es que el Engine de SQL pueda utilizar cualquier index que exista sobre el campo, que resulta en un index seek en lugar de un table scan (que es más costoso en performance).

Para que este un poco mas claro: Un index esta creado únicamente sobre el VALOR del campo. Si nuestra clausula de WHERE encierra el campo indexado en una funcion (como por ejemplo SUBSTRING o CONVERT), cualquier posibilidad de usar el index esta eliminada, porque el Engine de SQL debe procesar cada row a traves de la funcion para determinar si cumple o no la constante contra la cual se esta comparando.

Un ejemplo muy sencillo seria el siguiente:

WHERE SUBSTRING(Apellido, 1, 4,) = 'Rodr'

La clausula de arriba no es Sargeable, porque el hecho de que exista un SUBSTRING contra nuestro campo, obliga al Engine a procesar cada campo.

En cambio, la clausula de abajo utiliza directamente el campo y se compara contra una constante, por lo cual se puede utilizar el index de nuestro campo.

WHERE Apellido LIKE 'Rodr%'

Otro ejemplo, que normalmente engañaría a varios de nosotros, seria un query para sacar todos los registros insertados en una tabla el dia de hoy, basándonos en el campo FechaHoraInsercion, que tiene tanto la Fecha como la Hora en que fue insertado el registro.

Una de las maneras mas comunes de hacer este query es el parsear el valor de FechaHoraInsercion y hacer la comparacion en una sola clausula, como por ejemplo:


SELECT NumeroCliente, Nombre, Apellido
FROM Clientes
WHERE
CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, FechaHoraInsercion))) = CONVERT(DATETIME, FLOOR(CONVERT(FLOAT,getDate())))

A pesar de que existe un índice sobre el campo FechaHoraInsercion, de nuevo, no podría ser usado porque el valor del campo en los indices es constante, y aquí tiene que ser pasado por 2 funciones CONVERT y una FLOOR.

La manera mas óptima de hacer este query (y que fuera sargeable) seria:

SELECT NumeroCliente, Nombre, Apellido
FROM Clientes
WHERE
FechaHoraInsercion >= DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)
AND FechaHoraInsercion < DateAdd(Day, DateDiff(Day, 0, GetDate()), 1) [/sourcecode] A pesar de tener 2 clausulas de WHERE en lugar de solo 1, el hecho de que el engine pueda calcular el valor de la constante del lado derecho de la expresion  y simplemente compararlo contra los valores almacenados en el index de FechaHoraInsercion ya resulta en una búsqueda mas óptima. Espero que les sirva.

1 2 Scroll to top