En MS SQL Server, creo mis scripts para usar variables personalizables:
DECLARE @somevariable int
SELECT @somevariable = -1
INSERT INTO foo VALUES ( @somevariable )
Luego cambiaré el valor de @somevariable
en tiempo de ejecución, dependiendo del valor que desee en la situación particular. Como está en la parte superior del guión, es fácil de ver y recordar.
¿Cómo hago lo mismo con el cliente PostgreSQL psql
?
sql
postgresql
variables
psql
Craig Walker
fuente
fuente
Respuestas:
Las variables de Postgres se crean mediante el comando \ set, por ejemplo ...
... y luego puede ser sustituido, por ejemplo, como ...
... o ...
editar: a partir de psql 9.1, las variables se pueden expandir entre comillas como en:
En versiones anteriores del cliente psql:
... Si desea utilizar la variable como valor en una consulta de cadena condicional, como ...
... entonces debe incluir las comillas en la variable misma, ya que lo anterior no funcionará. En su lugar, defina su variable como tal ...
Sin embargo, si, como yo, te topaste con una situación en la que querías hacer una cadena a partir de una variable existente, encontré que el truco es este ...
¡Ahora tiene una variable entre comillas y sin comillas de la misma cadena! Y puedes hacer algo como esto ...
fuente
\set
es solo parapsql
herramientas, ¡no puede usarlo en procedimientos almacenados!psql
metacomandos con comandos\set
de PostgreSQL de manera confusa.\set myvariable 'value'
no no incluir ninguna cotización dentro de la variable, al contrario de lo que dice esta respuesta. En caso de duda, use\echo :myvariable
dentro de psql para mostrar el valor independientemente de cualquier consulta.Una última palabra sobre las variables PSQL:
No se expanden si los encierra entre comillas simples en la instrucción SQL. Por lo tanto, esto no funciona:
Para expandirse a un literal de cadena en una instrucción SQL, debe incluir las comillas en el conjunto de variables. Sin embargo, el valor de la variable ya debe estar entre comillas, lo que significa que necesita un segundo conjunto de comillas, y el conjunto interno debe escaparse. Por lo tanto necesitas:
EDITAR : comenzando con PostgreSQL 9.1, puede escribir en su lugar:
fuente
:'myvariable'
Puede intentar usar una cláusula WITH .
fuente
CREATE TABLE test (name VARCHAR, age INT);
INSERT INTO test (name, age) VALUES ('Jack', 21), ('Jill', 20);
WITH vars AS (SELECT N'Jack' AS name, 21 AS age) SELECT test.* FROM test, vars WHERE test.name = vars.name and test.age = vars.age;
Ouputs Jack y la edad de Jack, como se esperaba.create table t(x integer);
insert into t(x) with sub as (select 999 as num) select num from sub;
select * from t;
Específicamente para
psql
, también puede pasarpsql
variables desde la línea de comando; se pueden pasar con-v
. Aquí hay un ejemplo de uso:Tenga en cuenta que los dos puntos no están entre comillas, luego se cita el nombre de la variable. Sintaxis extraña, lo sé. Esto solo funciona en psql; no funcionará en (digamos) PgAdmin-III.
Esta sustitución ocurre durante el procesamiento de entrada en psql, por lo que no puede (por ejemplo) definir una función que use
:'filepath'
y espere que el valor de:'filepath'
cambie de sesión a sesión. Será sustituido una vez, cuando se defina la función, y luego será una constante después de eso. Es útil para los scripts pero no para el tiempo de ejecución.fuente
FWIW, el verdadero problema era que había incluido un punto y coma al final de mi comando \ set:
El punto y coma se interpretó como un carácter real en la variable:
Entonces cuando traté de usarlo:
...Tengo esto:
Eso no solo no pudo establecer las comillas alrededor del literal, sino que dividió el comando en 2 partes (la segunda de las cuales no era válida ya que comenzó con "NOINHERIT").
La moraleja de esta historia: las "variables" de PostgreSQL son realmente macros utilizadas en la expansión de texto, no valores verdaderos. Estoy seguro de que es útil, pero al principio es complicado.
fuente
Debe utilizar uno de los lenguajes de procedimiento, como PL / pgSQL, no el lenguaje de proceso SQL. En PL / pgSQL puede usar vars directamente en las declaraciones SQL. Para comillas simples puede usar la función literal de comillas.
fuente
postgres (desde la versión 9.0) permite bloques anónimos en cualquiera de los lenguajes de script del lado del servidor compatibles
http://www.postgresql.org/docs/current/static/sql-do.html
Como todo está dentro de una cadena, las variables de cadena externas que se sustituyan deberán escaparse y citarse dos veces. El uso de las cotizaciones en dólares en su lugar no dará una protección total contra la inyección de SQL.
fuente
Otro enfoque es (ab) usar el mecanismo PostgreSQL GUC para crear variables. Vea esta respuesta previa para detalles y ejemplos.
Declara el GUC en
postgresql.conf
, luego cambia su valor en tiempo de ejecución conSET
comandos y obtiene su valor concurrent_setting(...)
.No lo recomiendo para uso general, pero podría ser útil en casos limitados como el mencionado en la pregunta vinculada, donde el póster quería una forma de proporcionar el nombre de usuario a nivel de aplicación a los desencadenantes y funciones.
fuente
Lo resolví con una tabla temporal.
De esta manera, tenía una "variable" que podía usar en múltiples consultas, que es única para la sesión. Lo necesitaba para generar "nombres de usuario" únicos sin tener colisiones si importaba usuarios con el mismo nombre de usuario.
fuente
He encontrado esta pregunta y las respuestas extremadamente útiles, pero también confusas. Tuve muchos problemas para que las variables citadas funcionen, así que esta es la forma en que lo hice funcionar:
De esta manera puede definir la variable en una declaración. Cuando lo use, se incluirán comillas simples en la variable.
¡NOTA! Cuando puse un comentario después de la variable citada, se absorbió como parte de la variable cuando probé algunos de los métodos en otras respuestas. Eso realmente me estaba jodiendo por un tiempo. Con este método, los comentarios parecen ser tratados como es de esperar.
fuente
\set deployment_pass 'string_password'
ALTER USER :deployment_user WITH PASSWORD :'deployment_pass';
Realmente extraño esa característica. La única forma de lograr algo similar es usar funciones.
Lo he usado de dos maneras:
Versión Perl:
Versión de mesa:
Notas:
fuente
Variables en
psql
chupar. Si desea declarar un número entero, debe ingresar el número entero, luego hacer un retorno de carro, luego finalizar la declaración en punto y coma. Observar:Digamos que quiero declarar una variable entera
my_var
e insertarla en una tablatest
:Tabla de ejemplo
test
:Claramente, nada en esta tabla todavía:
Declaramos una variable. ¡Observe cómo está el punto y coma en la siguiente línea!
Ahora podemos insertar. Tenemos que usar esta extraña "
:''
" sintaxis de aspecto:¡Funcionó!
Explicación:
Entonces ... ¿qué pasa si no tenemos el punto y coma en la siguiente línea? ¿La variable? Echar un vistazo:
Declaramos
my_var
sin la nueva línea.Vamos a seleccionar
my_var
.¿Que demonios es eso? ¡No es un entero , es una cadena
999;
!fuente
He publicado una nueva solución para esto en otro hilo .
Utiliza una tabla para almacenar variables y se puede actualizar en cualquier momento. Una función getter estática inmutable se crea dinámicamente (por otra función), activada por la actualización de su tabla. Obtiene un buen almacenamiento de la mesa, además de las velocidades ultrarrápidas de un captador inmutable.
fuente