2009-09-29 34 views
112

¿Cómo declaro una variable para usar en una consulta de PostgreSQL 8.3?Cómo declarar una variable en una consulta de PostgreSQL

En MS SQL Server que pueda hacer esto:

DECLARE @myvar INT 
SET @myvar = 5 

SELECT * 
FROM somewhere 
WHERE something = @myvar 

¿Cómo puedo hacer lo mismo en PostgreSQL? De acuerdo con la documentación de las variables se declaran simplemente como "tipo de nombre;", pero esto me da un error de sintaxis:

myvar INTEGER; 

Podría alguien darme un ejemplo de la sintaxis correcta?

+2

Se puede hacer en tan sólo PostgreSQL. Consulte la respuesta a esta pregunta relacionada: http://stackoverflow.com/questions/766657/how-do-you-use-variables-in-a-simple-postgresql-script#6990059 –

+2

Esta respuesta relacionada tiene mejores respuestas: http://stackoverflow.com/questions/13316773/is-there-a-way-to-define-a-named-constant-in-a-postgresql-query –

Respuesta

52

No existe tal característica en PostgreSQL. Puede hacerlo solo en pl/PgSQL (u otro pl/*), pero no en SQL simple.

+13

¿A quién le importa explicar * por qué * esta respuesta está desactualizada? – simonlchilds

+20

Bien, entonces ¿cómo lo haces en pl/PgSQL ?! – stone

19

Usando una tabla temporal fuera de PL/pgSQL

Fuera de la utilización de pl/pgsql u otros pl/* lenguaje como se sugiere, esta es la única posibilidad que se me ocurría.

begin; 
select 5::int as var into temp table myvar; 
select * 
    from somewhere s, myvar v 
where s.something = v.var; 
commit; 
40

También puede probar esto en plpgsql:

DO $$ 
DECLARE myvar integer; 
BEGIN 
    SELECT 5 INTO myvar; 

    DROP TABLE IF EXISTS tmp_table; 
    CREATE TABLE tmp_table AS 
    SELECT * FROM yourtable WHERE id = myvar; 
END $$; 

SELECT * FROM tmp_table; 

Lo anterior requiere PostgreSQL 9.0 o superior.

+0

La declaración de DO se agregó en PostgreSQL 9.0 y no funciona en 8.3. – Johny

+7

Utilice CREATE TEMPORARY TABLE o CREATE TEMP TABLE, no CREATE TABLE. Pero por lo demás está bien. –

32

Depende de su cliente.

Sin embargo, si usted está utilizando el cliente psql, a continuación, puede utilizar el siguiente:

my_db=> \set myvar 5 
my_db=> SELECT :myvar + 1 AS my_var_plus_1; 
my_var_plus_1 
--------------- 
      6 
+1

'\ set' debe estar en minúscula – deluan

115

que logra el mismo objetivo mediante el uso de un WITH clause, que es ni de lejos tan elegante, pero puede hacer lo la misma cosa. Aunque para este ejemplo es realmente excesivo. Yo tampoco lo recomiendo particularmente.

WITH myconstants (var1, var2) as (
    values (5, 'foo') 
) 
SELECT * 
FROM somewhere, myconstants 
WHERE something = var1 
    OR something_else = var2; 
+2

Esto funciona muy bien para la mayoría de los casos en los que desearía variables. Sin embargo, si quisiera usar una variable para LIMIT (que no puede contener variables), entonces querrá usar '\ set' como se sugiere en la respuesta de Shahriar Aghajani. – cimmanon

+1

Esto es ideal para cuando tengo un script de migración donde quiero importar algunos datos relacionales. Obviamente, no sabré la id. De secuencia de los datos relacionales. – Relequestual

+2

Acabo de probar este enfoque, y encontré una forma quizás mejor: 'ÚNASE a myconstants ON true' y luego no hay necesidad de hacer la selección secundaria. – vektor

6

quiero proponer una mejora para @DarioBarrionuevo's answer, para que sea más simples tablas temporales de apalancamiento.

Ajustes
DO $$ 
    DECLARE myvar integer = 5; 
BEGIN 
    CREATE TEMP TABLE tmp_table ON COMMIT DROP AS 
     -- put here your query with variables: 
     SELECT * 
     FROM yourtable 
     WHERE id = myvar; 
END $$; 

SELECT * FROM tmp_table; 
+0

buena solución para resolver bloque DO no puede devolver el conjunto de datos! – CodeFarmer

26

dinámico de configuración

puede "abuso" ajustes de configuración dinámica para esto:

configuración
-- choose some prefix that is unlikey to be used by postgres 
set session my.vars.id = '1'; 

select * 
from person 
where id = current_setting('my.vars.id')::int; 

de configuración son siempre los valores varchar, por lo que necesita para echarlos al tipo de datos correcto cuando los usas Esto funciona con cualquier cliente SQL, mientras que \set solo funciona en psql

Lo anterior requiere Postgres 9.2 o posterior.

Para las versiones anteriores, la variable tenía que declararse en postgresql.conf antes de ser utilizada, por lo que limitaba su usabilidad de alguna manera. En realidad, no es la variable por completo, sino la "clase" de configuración, que es esencialmente el prefijo.Pero una vez se ha definido el prefijo, cualquier variable podría ser utilizado sin cambiar postgresql.conf

+0

puede esto 'set session my.vars.id' = '1'; ¿ser específico de la transección? –

+1

@BrijanElwadhi: sí, eso es transaccional. –

+0

gracias .. realmente me ayudó :) –

0

Aquí se muestra un ejemplo usando PREPARE statements. Todavía no se puede utilizar ?, pero se puede utilizar la notación $n:

PREPARE foo(integer) AS 
    SELECT * 
    FROM somewhere 
    WHERE something = $1; 
EXECUTE foo(5); 
DEALLOCATE foo; 
Cuestiones relacionadas