El comando EXECUTE STATEMENT puede ser muy útil para realizar muchas tareas porque nos permite armar la instrucción que necesitamos ejecutar de muchas maneras. El tema es: cuando la instrucción que queremos ejecutar requiere de variables ¿cómo la armamos?
Tenemos tres posibilidades:
- Concatenando los parámetros
- Usando parámetros con nombres
- Usando parámetros por posición
Ejemplo:
(Este es un ejemplo muy sencillo y hay mejores formas de resolverlo pero sirve para demostrar como usar EXECUTE STATEMENT con parámetros)
Queremos crear un stored procedure que nos muestre los productos cuyos precios de venta están dentro del rango especificado.
Esta es nuestra tabla de PRODUCTOS:
Captura 1. Si haces clic en la imagen la verás más grande
1. Concatenando los parámetros
CREATE PROCEDURE EXECUTE1( tnPrecio1 INTEGER, tnPrecio2 INTEGER) RETURNS( ftcNombre VARCHAR(40), ftnPrecio INTEGER) AS DECLARE VARIABLE lcComando VARCHAR(1000); BEGIN lcComando = 'SELECT PRD_NOMBRE, PRD_PREVTA FROM PRODUCTOS WHERE PRD_PREVTA >= ' || tnPrecio1 || ' AND PRD_PREVTA <= ' || tnPrecio2; FOR EXECUTE STATEMENT lcComando INTO :ftcNombre, :ftnPrecio DO BEGIN SUSPEND; END END;
Como este es un stored procedure seleccionable para ejecutarlo debemos escribir algo como:
SELECT * FROM EXECUTE1(3000, 5000)
y este será el resultado que obtendremos:
Captura 2. Si haces clic en la imagen la verás más grande
2. Usando parámetros con nombres
CREATE PROCEDURE EXECUTE2( tnPrecio1 INTEGER, tnPrecio2 INTEGER) RETURNS( ftcNombre VARCHAR(40), ftnPrecio INTEGER) AS DECLARE VARIABLE lcComando VARCHAR(1000); BEGIN lcComando = 'SELECT PRD_NOMBRE, PRD_PREVTA FROM PRODUCTOS WHERE PRD_PREVTA >= :lnPrecio1 AND PRD_PREVTA <= :lnPrecio2'; FOR EXECUTE STATEMENT (lcComando) (lnPrecio1 := tnPrecio1, lnPrecio2 := tnPrecio2) INTO :ftcNombre, :ftnPrecio DO BEGIN SUSPEND; END END;
En este caso dentro de lcComando usamos dos variables locales llamadas lnPrecio1 y lnPrecio2. Pero esas variables no es necesario declararlas después del AS (puedes declararlas si quieres, pero no es necesario).
Como estamos usando parámetros con nombres, no importa el orden en el cual especificamos los parámetros. O sea que ambas de estas formas son equivalentes, podemos usar cualquiera de ellas:
FOR EXECUTE STATEMENT (lcComando) (lnPrecio1 := tnPrecio1, lnPrecio2 := tnPrecio2) FOR EXECUTE STATEMENT (lcComando) (lnPrecio2 := tnPrecio2, lnPrecio1 := tnPrecio1)
Como puedes ver nuestros parámetros tienen nombres (en este ejemplo: lnPrecio1 y lnPrecio2)
3. Usando parámetros por posición
CREATE PROCEDURE EXECUTE3( tnPrecio1 INTEGER, tnPrecio2 INTEGER) RETURNS( ftcNombre VARCHAR(40), ftnPrecio INTEGER) AS DECLARE VARIABLE lcComando VARCHAR(1000); BEGIN lcComando = 'SELECT PRD_NOMBRE, PRD_PREVTA FROM PRODUCTOS WHERE PRD_PREVTA >= ? AND PRD_PREVTA <= ?'; FOR EXECUTE STATEMENT (lcComando) (tnPrecio1, tnPrecio2) INTO :ftcNombre, :ftnPrecio DO BEGIN SUSPEND; END END;
En este caso, el primer signo de interrogación dentro de lcComando es reemplazado por el primer parámetro enviado. El segundo signo de interrogación por el segundo parámetro y así sucesivamente. Por lo tanto aquí sí importa el orden en el cual enviamos los parámetros. Si enviamos los parámetros con el orden equivocado (es decir: primero tnPrecio2 y después tnPrecio1) entonces obtendremos un resultado erróneo.
Conclusión:
Poder enviarle parámetros al comando que ejecutamos con EXECUTE STATEMENT es muy útil y nos permite escribir código fuente más confiable.
En general es preferible enviar parámetros con nombres porque eso disminuye la probabilidad de cometer errores. Además, si un parámetro se usará varias veces dentro de lcComando con enviarlo una sola vez será suficiente.
La ventaja de enviar los parámetros por posición es que se escribe menos. La desventaja es que si equivocamos el orden de los parámetros enviados el resultado que obtendremos será erróneo. Y si un parámetro se necesita varias veces tendremos que enviarlo varias veces.
La opción de concatenar los parámetros es la menos recomendable porque cuando lcComando es largo y recibe varios parámetros tantas concatenaciones pueden marear a cualquiera
Artículos relacionados:
jhironsel
Oct 27, 2023 @ 09:29:48
Esto esta muy bien para cuando los parámetros son numéricos, pero la cosa se pone fea cuando los valores son alfanumérico y llevan comillas simples. Los métodos por parámetros por posición y parámetros por nombres no me funcionan bien.
Cual seria la solución a eso?
Saludos..