jueves, 12 de noviembre de 2009

Generar automáticamente procedimientos almacenados a partir de una tabla

La creación de procedimientos almacenados para un CRUD puede resultar una tarea bastante repetitiva. Aquí publico un procedimiento almacenado para SQL Server (T-SQL) que sirve para generar un script para crear 4 procedimientos almacenados a partir del nombre de una tabla.

El script creará 4 procedimientos. Todos los procedimientos que crea el script reciben como parámetros todos los campos de la tabla.
- SELECT filtrará por los campos recibidos que no sean NULL (where condicionado)
- INSERT insertará un registro con los parámetros recibidos
- UPDATE tal y como se genera no tiene sentido, simplemente borra las líneas que no quieras (del SET ó del WHERE)
- DELETE borrará registros filtrando por los campos recibidos que no sean NULL
- EXISTS devolverá registros que coincidan con el filtro creado con los campos recibidos que no sean NULL (where condicionado)

Aquí está el script:
CREATE PROCEDURE [dbo].[sp_generate]
  @tableName AS VARCHAR(100)
AS

--CAPITALIZE TABLENAME
SET @tableName = UPPER(LEFT(@tableName,1)) + RIGHT(@tableName, LEN(@tableName) -1)

--SALTO DE LÍNEA
DECLARE @nl AS CHAR
SET @nl = CHAR(10) + CHAR(13) 

--CABECERA
DECLARE @spHeaders AS VARCHAR(1000)
SET @spHeaders = 'SET ANSI_NULLS ON' + @nl +
'GO' + @nl +
'SET QUOTED_IDENTIFIER ON' + @nl +
'GO' + @nl +
'-- =============================================' + @nl +
'-- Author:  TU_NOMBRE' + @nl +
'-- Create date: ' + CONVERT(VARCHAR, GETDATE(), 3) + @nl +
'-- ============================================='

DECLARE @table AS VARCHAR(MAX)
DECLARE @column AS VARCHAR(MAX)
DECLARE @data_type AS VARCHAR(MAX)
DECLARE @length AS INT
DECLARE @precision AS INT
DECLARE @scale AS INT

--PARÁMETROS
DECLARE @spParameters AS VARCHAR(MAX) SET @spParameters = ''

--LISTA DE CAMPOS
DECLARE @fieldList AS VARCHAR(MAX) SET @fieldList = ''

--LISTA DE CAMPOS PARA EL SET DEL UPDATE
DECLARE @fieldSetList AS VARCHAR(MAX) SET @fieldSetList = ''

--LISTA DE PARÁMETROS PARA EL INSERT
DECLARE @insertParameters AS VARCHAR(MAX) SET @insertParameters = ''

--CONDICIONES
DECLARE @spConditions AS VARCHAR(MAX) SET @spConditions = ''

DECLARE c CURSOR STATIC FOR
select table_name, column_name, data_type, character_maximum_length,numeric_precision, numeric_scale from information_schema.columns where table_name = @tableName order by ordinal_position
OPEN c FETCH NEXT FROM c INTO @table, @column, @data_type, @length, @precision, @scale
WHILE @@FETCH_STATUS = 0 BEGIN

 SET @spParameters = @spParameters + (CASE WHEN LEN(@spParameters) >0 THEN @nl + ' ,' ELSE '  ' END) + '@' + @column + ' ' + UPPER(@data_type) + (CASE @data_type WHEN 'VARCHAR' THEN '('+CAST(@length AS VARCHAR)+')' WHEN 'DECIMAL' THEN '('+CAST(@precision AS VARCHAR)+', '+CAST(@scale AS VARCHAR)+')' ELSE '' END) + ' = NULL'
 SET @fieldList = @fieldList + (CASE WHEN LEN(@fieldList) >0 THEN @nl + '    ,' ELSE '' END) + @column
 SET @spConditions = @spConditions + (CASE WHEN LEN(@spConditions) >0 THEN @nl + '   AND ' ELSE '' END) + '(@' + @column + ' IS NULL OR @' + @column + '=' + @column + ')'
 SET @fieldSetList = @fieldSetList + (CASE WHEN LEN(@fieldSetList) >0 THEN @nl + '     ,' ELSE '      ' END) + @column + ' = @' + @column
 SET @insertParameters = @insertParameters + (CASE WHEN LEN(@insertParameters) >0 THEN @nl + '    ,' ELSE '' END) + '@' + @column

 FETCH NEXT FROM c INTO @table, @column, @data_type, @length, @precision, @scale
END
CLOSE c DEALLOCATE c

--********************************
--*********** SELECT *************
--********************************
DECLARE @SELECT AS VARCHAR(MAX)
SET @SELECT = @spHeaders + @nl
SET @SELECT = @SELECT + 'CREATE PROCEDURE ' + @tableName + '_Select' + @nl
SET @SELECT = @SELECT + @spParameters + @nl
SET @SELECT = @SELECT + 'AS' + @nl + ' SET NOCOUNT OFF;' + @nl + @nl
SET @SELECT = @SELECT + '    SELECT ' + @fieldList + @nl
SET @SELECT = @SELECT + '    FROM ' + @table + @nl
SET @SELECT = @SELECt + '    WHERE ' + @spConditions + @nl

--********************************
--*********** UPDATE *************
--********************************
DECLARE @UPDATE AS VARCHAR(MAX)
SET @UPDATE = @spHeaders + @nl
SET @UPDATE = @UPDATE + 'CREATE PROCEDURE ' + @tableName + '_Update' + @nl
SET @UPDATE = @UPDATE + @spParameters + @nl
SET @UPDATE = @UPDATE + 'AS' + @nl + ' SET NOCOUNT OFF;' + @nl + @nl
SET @UPDATE = @UPDATE + '    UPDATE ' + @table + ' SET ' + @nl
SET @UPDATE = @UPDATE + @fieldSetList + @nl
SET @UPDATE = @UPDATE + '    WHERE ' + @spConditions + @nl

--********************************
--*********** DELETE *************
--********************************
DECLARE @DELETE AS VARCHAR(MAX)
SET @DELETE = @spHeaders + @nl
SET @DELETE = @DELETE + 'CREATE PROCEDURE ' + @tableName + '_Delete' + @nl
SET @DELETE = @DELETE + @spParameters + @nl
SET @DELETE = @DELETE + 'AS' + @nl + ' SET NOCOUNT OFF;' + @nl + @nl
SET @DELETE = @DELETE + '    DELETE FROM ' + @table + @nl
SET @DELETE = @DELETE + '    WHERE ' + @spConditions + @nl

--********************************
--*********** INSERT *************
--********************************
DECLARE @INSERT AS VARCHAR(MAX)
SET @INSERT = @spHeaders + @nl
SET @INSERT = @INSERT + 'CREATE PROCEDURE ' + @tableName + '_Insert' + @nl
SET @INSERT = @INSERT + @spParameters + @nl
SET @INSERT = @INSERT + 'AS' + @nl + ' SET NOCOUNT OFF;' + @nl + @nl
SET @INSERT = @INSERT + '    INSERT INTO ' + @table + '(' + @nl
SET @INSERT = @INSERT + '     ' + @fieldList + @nl
SET @INSERT = @INSERT + ' )' + @nl + ' VALUES(' + @nl + '     ' + @insertParameters + @nl
SET @INSERT = @INSERT + ' )' + @nl

--********************************
--*********** EXISTS *************
--********************************
DECLARE @EXISTS AS VARCHAR(MAX)
SET @EXISTS = @spHeaders + @nl
SET @EXISTS = @EXISTS + 'CREATE PROCEDURE ' + @tableName + '_Exists' + @nl
SET @EXISTS = @EXISTS + @spParameters + @nl
SET @EXISTS = @EXISTS + ' ,@exists BIT OUT' + @nl
SET @EXISTS = @EXISTS + 'AS' + @nl + ' SET NOCOUNT OFF;' + @nl + @nl
SET @EXISTS = @EXISTS + '    IF EXISTS (' + @nl + ' SELECT ' + LEFT(@fieldList,CHARINDEX(@nl,@fieldList))
SET @EXISTS = @EXISTS + '    FROM ' + @table + @nl
SET @EXISTS = @EXISTS + '    WHERE ' + @spConditions + @nl + ' )' + @nl
SET @EXISTS = @EXISTS + ' SET @exists = 1' + @nl + ' ELSE SET @exists = 0'

--MOSTRAR GENERADOS
PRINT + '-- =====INSERT==================================' + @nl + @INSERT
PRINT + '-- =====DELETE==================================' + @nl + @DELETE
PRINT + '-- =====UPDATE==================================' + @nl + @UPDATE
PRINT + '-- =====SELECT==================================' + @nl + @SELECT
PRINT + '-- =====EXISTS==================================' + @nl + @EXISTS

Se usa así:
sp_generate NOMBRE_DE_TABLA

martes, 10 de noviembre de 2009

Nokia WRT, Aptana, Firefox y cross site javascripts

El "cross-site scripting" es la base de todo widget que realiza llamadas AJAX. Pero es algo que no está permitido en los navegadores convencionales.

Si previsualizas tus widgets con firefox necesitas hacer los dos pasos siguientes para poder usar "cross-site scripting" y emular correctamente el comportamiento del terminal symbian:

1 - Antes de la llamada AJAX debes ejecutar la siguiente sentencia: netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

2 - Establece a "true" el valor de la clave "signed.applets.codebase_principal_support" en about:config

¡Y ya puedes previsualizar tus widgets que realizan cross-side scripting!

IMPORTANTE: No olvides comentar la línea netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); antes de instalar la aplicación en el terminal

jueves, 5 de noviembre de 2009

Simulador de préstamos para Symbian S60 V3 y V5

Compatible con los terminales Symbian S60 V3 (N78, N82, N95...) y V5 (5800, N97, 5530...). Es un simulador de préstamos que muestra la tabla de amortización del mismo. Se puede obtener la tabla de amortización de un préstamo francés (cuota constante) ó un préstamo alemán (capital constante). Para calcular tu hipoteca, el préstamo del coche, etc...

¡ACTUALIZACIÓN!: Está disponible para descargar la versión 1.1. Estos son los cambios:
- Compatible con terminales Symbian V3
- Durante la generación de la tabla se muestra una barra que indica el progreso
- Posibilidad de cancelar la generación (Sólo Symbian V5)
- Arreglado un pequeño desajuste para préstamos de tipo Capital Constante que ocurría algunas veces



S60 V5





S60 V3




Si alguien pone el programa en otra web u otro foro, me gustaría pedirle que enlace a la misma dirección (mi blog), no es necesario volver a subirlo a megaupload ni a rapidshare. Las próximas actualizaciones estarán disponibles ahí. Es lo único que pido a cambio de regalar mi trabajo.

Las actualizaciones las podrás encontrar aquí.

miércoles, 4 de noviembre de 2009

Aramemeo Online: Generador de frases estúpidas aleatorias

Pulsando sobre "Generar" puedes obtener cientos de frases completamente aleatorias. Este texto aleatorio puedes usarlo para maquetar tu web, ó para cualquier cosa como alternativa al conocidísimo "lore ipsum".

También está disponible para móviles Symbian V3 y V5: http://sviudes.blogspot.com/2009/11/aramemeo-generador-de-frases-estupidas.html


Long.palabra:
de

a

Palabras:
de

a



Aramemeo: Generador de frases estúpidas aleatorias para Symbian V3 y V5

Esta inútil pero curiosa aplicación genera cientos de frases de forma completamente aleatoria, sin nungún sentido... ¿para qué sirve esto?... la verdad es que todavía no lo se...

También lo puedes usar online: http://sviudes.blogspot.com/2009/11/aramemeo-online-generador-de-frases.html





Si alguien pone el programa en otra web u otro foro, me gustaría pedirle que enlace a la misma dirección (mi blog), no es necesario volver a subirlo a megaupload ni a rapidshare. Las próximas actualizaciones estarán disponibles ahí. Es lo único que pido a cambio de regalar mi trabajo.

lunes, 2 de noviembre de 2009

ResolveURL en ASP.NET sin Page

Programando en Asp.net estoy acostumbrado a usar ResolveURL cada vez que quiero obtener una dirección completa a partir de una de la forma ~/carpeta/fichero.aspx. En ocasiones no disponemos del objeto Page para acceder a este método (por ejemplo en una librería de funciones). Para solucionar este problema usamos al método VirtualPathUtility.ToAbsolute(url).