Así que tengo esta función de PostgreSQL, que toma un número variable de argumentos con nombre y devuelve una lista de los elementos correspondientes:
CREATE OR REPLACE FUNCTION read_user( _id BIGINT DEFAULT NULL, _phone VARCHAR(30) DEFAULT NULL, _type VARCHAR(15) DEFAULT NULL, _last VARCHAR(50) DEFAULT NULL, _first VARCHAR(50) DEFAULT NULL ) RETURNS setof T_USERS AS $$ BEGIN RETURN QUERY SELECT * FROM T_USERS WHERE ( id = _id OR _id IS NULL ) AND ( phone = _phone OR _phone IS NULL ) AND ( type = _type OR _type IS NULL ) AND ( last = _last OR _last IS NULL ) AND ( first = _first OR _first IS NULL ); EXCEPTION WHEN others THEN RAISE WARNING 'Transaction failed and was rolled back'; RAISE NOTICE '% %', SQLERRM, SQLSTATE; END $$ LANGUAGE plpgsql;Entonces puedo ejecutar consultas polimórficas como estas:
SELECT read_user(_id := 2); SELECT read_user(_first := 'John', _last := 'Doe');En Golang puedo hacer algo como:
stmt, err := db.Prepare("SELECT read_user(_id = ?)") Pero, ¿cómo puedo hacer lo mismo, pero con una cantidad variable de argumentos read_user ? Estoy usando el controlador pq https://github.com/lib/pq .
Puede construir su única declaración enumerando todos los parámetros con sus marcadores de posición y luego podría pasar nil explícitamente donde no tiene el valor del parámetro.
stmt, err := db.Prepare("SELECT read_user(_id := $1, _phone := $2, _type := $3, _last := $4, _first := $5)") if err != nil { // ... } stmt.Query(2, nil, nil, nil, nil) // result should be equivalent to `SELECT read_user(_id := 2)` stmt.Query(nil, nil, nil, "Doe", "John") // result should be equivalent to `SELECT read_user(_first := 'John', _last := 'Doe')`Y si también desea tener parámetros con nombre en Go, puede crear un tipo de estructura para representar los parámetros y una función contenedora que asignará los campos de ese tipo de parámetro a la consulta:
type readUserParams struct { Id interface{} Phone interface{} Type interface{} Last interface{} First interface{} } func readUser(p *readUserParams) { stmt.Query(p.Id, p.Phone, p.Type, p.Last, p.First) // ... } readUser(&readUserParams{Id: 2}) readUser(&readUserParams{First: "John", Last:"Doe"})