Category Archives: Code Snippet

Configuración del Formato de Fechas en SQL SERVER

 

Aunque lo ideal es encapsular las variables de fecha en parámetros ya formateados en ocasiones (sobretodo en proyectos viejos) te encuentras con algunas consultas con las fechas directamente en string como el típico:

SELECT * FROM Pedidos WHERE FechaPedido >= '30/01/2011'

Es posible que esta consulta funcione correctamente en tu servidor de SQL SERVER local pero al llevarlo a producción te encuentres en ocasiones con el típico error:

La conversión del tipo de datos varchar en datetime produjo un valor fuera de intervalo / The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

Este error ocurre cuando el servidor intenta comparar una columna con formato “DateTime” (como es el campo “FechaPedido” de nuestro ejemplo) con un String pasado como parámetro y, al intentar convertirlo se desborda.

¿Por qué ocurre esto? Porque el idioma del servidor le indica que debe interpretar las fechas de otro modo y al convertir el String en Date da un valor incorrecto (lo más clásico es que lo intente convertir en MM/DD/YYYY y como el mes 30 no existe pasa lo que pasa…).

 

Hay varias formas de solucionar este problema aunque, como he dicho al principio del post, lo ideal es pasar la fecha en una variable ya formateada como Date usando tecnologías de acceso a datos como Entity Framework, Linq o con los DataSets de ADO.NET.

 

Como SysAdmin: Modificar la configuración global de idioma del servidor

Si queremos modificar el idioma predeterminado de TODO el servidor para TODAS las bases de datos podemos hacer los siguiente:

Como “sa” y contra “master” ejecutamos lo siguiente:

SP_CONFIGURE 'default language', 5

RECONFIGURE;

Dónde el 5 pasado como parámetro es el idioma “Español” con formato de fecha “dd/mm/yyyy”.

Si queremos establecer otro idioma y no sabemos su identificador usad esta consulta:

USE master
SELECT * FROM syslanguages

De este modo todo nuevo login contra el servidor de base de datos usará este idioma por defecto y afectará a toda conversión de fecha que se solicite (como en la SELECT del ejemplo, un DATEDIFF o un DATENAME para obtener el nombre del día o mes).

 

Como SysAdmin: Modificar la configuración de idioma de un login en concreto

Si no queremos cambiar la configuración de idioma de todo el servidor (cosa lógica si hay otras bases de datos funcionando y no queremos modificar su comportamiento) podemos modificar sólo la configuración de idioma de un login en concreto para que cualquier consulta contra cualquier base de datos que lance dicho login utilice el idioma indicado.

La consulta para cambiar el idioma de un login es:

EXEC sp_defaultlanguage 'nombre del login', 'idioma'

Dónde “idioma” es el nombre del idioma que queremos establecer que podemos obtener del campo “name” de la tabla “master.syslanguages” tal y cómo hemos explicado antes.

 

Al igual que con el otro método es necesario que el usuario vuelva a reconectarse para hacer uso de la nueva configuración.

 

Como desarrollador: Establecer el idioma antes de hacer una consulta

Si no tienes más remedio que hacer una consulta pasando fechas como string puedes asegurarte de escoger el formato antes de realizar la consulta. Para ello basta con añadir la siguiente clausula ANTES de hacer la consulta:

SET LANGUAGE 'idioma'

Con lo que podríamos hacer que nuestra consulta de ejemplo funcione siempre en cualquier servidor sea cual sea el idioma del mismo haciendo la consulta así:

SET LANGUAGE 'español';

SELECT * FROM Pedidos WHERE FechaPedido >= '30/01/2011';

De este modo nos aseguramos que la conversión de la fecha siempre sea con formato del idioma “español” que es dd/mm/yyyy

 

Depende del escenario que tengas deberás usar un método u otro aunque, lo siento por repetirme, lo mejor es controlar el formato de la fecha a nivel de aplicación y no ir modificando la configuración del servidor.

 

 

Nos vemos compilando!!

Code Snippet: LastIndexOf en SQL SERVER

Uno de los mótivos que me impulsó a abrir el blog es para usarlo también como “bloc de notas” e ir anotando pequeños apuntes de código que me han parecido interesanto o que me han resulto un problema. 

Estrenamos esta categoría llamada “Code Snippet” con una pequeña consulta en T-SQL para SQL SERVER que sirve para obtener la última aparación de un caracter en concreto en un string; vamos, lo que ha hecho toda la vida el método LastIndexOf() de .NET pero que SQL no incluye por defecto.

 

 

LEN(STRING) - CHARINDEX('CHAR TO SEARCH', REVERSE(STRING)) + 1

 

 

Básicamente le doy la vuelta al string y obtengo la primera aparición del caracter a buscar.

Un ejemplo de uso para buscar, por ejemplo, la posición de última “/” en un string sería así:

 

SELECT LEN('C:/Dir/File.txt') - CHARINDEX('/', REVERSE('C:/Dir/File.txt')) + 1;

 

Esta consulta devolvería “11”. Si queremos quedarnos con lo que hay después (como ha sido mi caso, que necesitaba el “File.txt”), la consulta quedaría así:

 

SELECT RIGHT('C:/Dir/File.txt', CHARINDEX('/', REVERSE('C:/Dir/File.txt')) - 1);

 

Espero que os sea de ayuda.

 

Nos vemos Compilando!!