Me pregunto si es posible pasar parámetros a una consulta escrita en PL/pgSQL.
Intenté esto, pero falló con pq: got 1 parameters but the statement requires 0
package main import ( "database/sql" "fmt" "log" _ "github.com/lib/pq" ) func main() { db, err := sql.Open("postgres", "host=localhost dbname=db user=user sslmode=disable password=pw") if err != nil { log.Fatal(err) } row := db.QueryRow(` DO $$ BEGIN IF true THEN SELECT $1; END IF; END$$ `, 1) var num int err = row.Scan(&num) if err != nil { log.Fatal(err) } fmt.Println(num) } Otra pregunta relacionada es que quiero usar transacciones, pero las API proporcionadas por el paquete sql parecen conectarse a db cada vez que se ejecuta una consulta en un tx. Me gustaría que todo se ejecutara de una vez si eso es posible. Por ejemplo, con go se supone que debes usar transacciones como esta
tx, err := db.Begin() rows, err := tx.Query(sql1) result, err := tx.Exec(sql2) tx.Commit() El problema es que llamar a tx.Query y tx.Exec hace dos viajes al servidor PostgreSQL si no me equivoco. Lo que quiero lograr es fusionar sql1 y sql2 , envolverlos dentro de BEGIN y END y ejecutarlos en un solo viaje. Y mi pregunta es que:
Obtuvo un error porque se supone que PL/pgSQL debe definirse en el lado del servidor como function o procedure , pero en su caso, se llama desde el lado del cliente. A continuación se muestra un ejemplo simple sobre cómo definir y llamar a la función con parámetro(s):
CREATE OR REPLACE FUNCTION myadd(a integer, b integer) RETURNS integer AS $$ BEGIN RETURN a + b; END; $$ LANGUAGE plpgsql; Luego, desde el lado del cliente, puede llamar a la función con parámetros usando la consulta SELECT . Tenga en cuenta que, aunque su función contiene INSERT/UPDATE , la función debe llamarse mediante la instrucción SELECT .
//... a := 10 row := db.QueryRow(`SELECT * FROM myadd($1, $2)`, a, 130) //...Siguiente pregunta, sobre transacciones y PL/pgSQL. Sí, usando PL/pgSQL puede reducir el tráfico de red. Varias ventajas del lenguaje del lado del servidor (PL/pgSQL) son:
La regla cuando se trata de bases de datos (grandes datos) es You need to avoid to move your data around y PL/pgSQL se ajusta a esta regla. Sin embargo, hay algunas circunstancias en las que no puede (debe evitar) usar PL/pgSQL, por ejemplo, el administrador de base de datos/propietario del servidor no permite la programación del lado del servidor (razón de seguridad/rendimiento, etc.).
La relación entre function y la transaction se establece claramente en el manual :
Es importante no confundir el uso de BEGIN/END para agrupar declaraciones en PL/pgSQL con los comandos SQL de nombre similar para el control de transacciones. Los BEGIN/END de PL/pgSQL son solo para agrupar; no inician ni finalizan una transacción. Las funciones y los procedimientos desencadenantes siempre se ejecutan dentro de una transacción establecida por una consulta externa: no pueden iniciar o confirmar esa transacción, ya que no habría contexto para que se ejecuten. Sin embargo, un bloque que contiene una cláusula EXCEPTION forma efectivamente una subtransacción que puede revertirse sin afectar la transacción externa
En resumen, al usar PL/pgSQL puede obtener una mejora en el rendimiento. ¿Cuánto cuesta? Depende de. Tenga en cuenta que después de usar PL/pgSQL necesita administrar más de una base de código y, a veces, es difícil de depurar.