En esta sección, seguimos la convención habitual de Tcl de utilizar signos de interrogación, en lugar de corchetes, para indicar un elemento opcional en una sinopsis de sintaxis. Los siguientes comandos están disponibles para acceder a la base de datos desde el cuerpo de una función PL/Tcl:
spi_exec ?-count n? ?-array name? command ?loop-body?
Ejecuta un comando SQL dado como una cadena. Un error en el comando
hace que se lance un error. De lo contrario, el valor de retorno de spi_exec
es el número de filas procesadas (seleccionadas, insertadas, actualizadas o
eliminadas) por el comando, o cero si el comando es una sentencia de utilidad.
Además, si el comando es una sentencia SELECT, los
valores de las columnas seleccionadas se colocan en variables de Tcl como
se describe a continuación.
El valor opcional -count le dice a
spi_exec que se detenga
una vez que se hayan recuperado n filas,
como si la consulta incluyera una cláusula LIMIT.
Si n es cero, la consulta se ejecuta hasta
completarse, lo mismo que cuando se omite -count.
Si el comando es una sentencia SELECT, los valores de las
columnas del resultado se colocan en variables de Tcl que llevan el nombre de las columnas.
Si se proporciona la opción -array, los valores de las columnas se
almacenan en su lugar en elementos del array asociativo nombrado, con los
nombres de las columnas utilizados como índices del array. Además, el número de fila actual
dentro del resultado (contando desde cero) se almacena en el elemento del array
llamado “.tupno”, a menos que ese nombre esté
en uso como un nombre de columna en el resultado.
Si el comando es una sentencia SELECT y no se proporciona un script de
loop-body, entonces solo la primera fila de los resultados se almacena en
variables de Tcl o elementos del array; las filas restantes, si las hay, se ignoran.
No se realiza ningún almacenamiento si la consulta no devuelve filas. (Este caso se puede
detectar comprobando el resultado de spi_exec).
Por ejemplo:
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
establecerá la variable Tcl $cnt al número de filas en
el catálogo del sistema pg_proc.
Si se proporciona el argumento opcional loop-body, es
un fragmento de script de Tcl que se ejecuta una vez para cada fila en el
resultado de la consulta. (loop-body se ignora si el comando
dado no es un SELECT).
Los valores de las columnas de la fila actual
se almacenan en variables de Tcl o elementos del array antes de cada iteración.
Por ejemplo:
spi_exec -array C "SELECT * FROM pg_class" {
elog DEBUG "have table $C(relname)"
}
imprimirá un mensaje de registro para cada fila de pg_class. Esta
característica funciona de manera similar a otras estructuras de bucle de Tcl; en
particular, continue y break funcionan de la
manera habitual dentro del cuerpo del bucle.
Si una columna de un resultado de consulta es null, la variable de destino para ella se elimina (“unset”) en lugar de establecerse.
spi_prepare query typelistPrepara y guarda un plan de consulta para una ejecución posterior. El plan guardado se conservará durante la vida de la sesión actual.
La consulta puede usar parámetros, es decir, marcadores de posición para
valores que se proporcionarán cada vez que el plan se ejecute realmente.
En la cadena de consulta, haz referencia a los parámetros
mediante los símbolos $1 ... $.
Si la consulta utiliza parámetros, los nombres de los tipos de parámetros
deben proporcionarse como una lista de Tcl. (Escribe una lista vacía para
ntypelist si no se utilizan parámetros).
El valor de retorno de spi_prepare is a query ID
que se utilizará en llamadas posteriores a spi_execp. Consulta
spi_execp para ver un ejemplo.
spi_execp ?-count n? ?-array name? ?-nulls string? queryid ?value-list? ?loop-body?
Ejecuta una consulta previamente preparada con spi_prepare.
queryid es el ID devuelto por
spi_prepare. Si la consulta hace referencia a parámetros,
se debe proporcionar una value-list. Esta
es una lista de Tcl con los valores reales para los parámetros. La lista debe tener
la misma longitud que la lista de tipos de parámetros proporcionada anteriormente a
spi_prepare. Omite value-list
si la consulta no tiene parámetros.
El valor opcional para -nulls es una cadena de espacios y
caracteres 'n' que le dice a spi_execp
cuáles de los parámetros son valores null. Si se proporciona, debe tener exactamente la
misma longitud que la value-list. Si no
se proporciona, todos los valores de los parámetros se consideran no null.
Excepto por la forma en que se especifican la consulta y sus parámetros,
spi_execp funciona igual que spi_exec.
Las opciones -count, -array y
loop-body son las mismas,
y también lo es el valor del resultado.
Aquí tienes un ejemplo de una función PL/Tcl que utiliza un plan preparado:
CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
if {![ info exists GD(plan) ]} {
# preparar el plan guardado en la primera llamada
set GD(plan) [ spi_prepare \
"SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \
[ list int4 int4 ] ]
}
spi_execp -count 1 $GD(plan) [ list $1 $2 ]
return $cnt
$$ LANGUAGE pltcl;
Necesitamos barras invertidas dentro de la cadena de consulta dada a
spi_prepare para asegurar que los marcadores
$ se pasen
a nspi_prepare tal cual, y no se reemplacen por la sustitución
de variables de Tcl.
subtransaction command
El script de Tcl contenido en command se
ejecuta dentro de una subtransacción SQL. Si el script devuelve un
error, toda esa subtransacción se revierte antes de devolver el
error al código Tcl circundante.
Consulta Section 42.9 para más detalles y un
ejemplo.
quote string
Duplica todas las apariciones de comillas simples y caracteres de barra invertida
en la cadena dada. Esto se puede usar para entrecomillar de forma segura cadenas
que se van a insertar en comandos SQL dados
a spi_exec o
spi_prepare.
Por ejemplo, piensa en una cadena de comando SQL como:
"SELECT '$val' AS ret"
donde la variable Tcl val realmente contiene
doesn't. Esto resultaría
en la cadena de comando final:
SELECT 'doesn't' AS ret
lo que causaría un error de análisis durante
spi_exec o
spi_prepare.
Para funcionar correctamente, el comando enviado debería contener:
SELECT 'doesn''t' AS ret
que se puede formar en PL/Tcl usando:
"SELECT '[ quote $val ]' AS ret"
Una ventaja de spi_execp es que no
tienes que entrecomillar los valores de los parámetros como este, ya que los parámetros nunca
se analizan como parte de una cadena de comando SQL.
elog level msg
Emite un mensaje de registro o error. Los niveles posibles son
DEBUG, LOG, INFO,
NOTICE, WARNING, ERROR y
FATAL. ERROR
lanza una condición de error; si esta no es capturada por el código
Tcl circundante, el error se propaga a la consulta que llama, lo que hace
que la transacción o subtransacción actual se aborte. Esto
es efectivamente lo mismo que el comando error de Tcl.
FATAL aborta la transacción y hace que la sesión
actual se cierre. (Probablemente no haya una buena razón para usar
este nivel de error en funciones PL/Tcl, pero se proporciona para
completitud). Los otros niveles solo generan mensajes de diferentes
niveles de prioridad.
Si los mensajes de una prioridad particular se reportan al cliente,
se escriben en el registro del servidor o ambos está controlado por las variables
de configuración log_min_messages y
client_min_messages. Consulta Chapter 19
y Section 42.8
para más información.