У меня есть несколько подробный запрос в скрипте, который использует ?
заполнители. Я хотел протестировать этот же запрос непосредственно из командной строки psql (вне сценария). Я хочу избежать замены всех ?
фактических значений, вместо этого я хотел бы передать аргументы после запроса.
Пример:
SELECT *
FROM foobar
WHERE foo = ?
AND bar = ?
OR baz = ? ;
Ищу что-то вроде:
%> {select * from foobar where foo=? and bar=? or baz=? , 'foo','bar','baz' };
postgresql
parameters
vol7ron
источник
источник
Ответы:
Вы можете использовать конструкцию -v, например
а затем ссылаться на переменные в sql как: v1,: v2 и т. д.
select * from table_1 where id = :v1;
Обратите внимание, как мы передаем значение строки / даты, используя две кавычки
" '...' "
источник
\set v3 'another value'
. Просто помните, когда вам нужноSELECT * FROM foo WHERE bar = :'v3';
awk
psql -v v1=12 -v v2="'Hello World'" -v v3="'2010-11-12'" -c 'select * from table_1 where id = :v1;'
сгенерирует синтаксическую ошибку. Однако, если вашей оболочкой является bash, вы можете попробовать:psql -v v1=12 -v v2="'Hello World'" -v v3="'2010-11-12'" <<< 'select * from table_1 where id = :v1;'
с хорошим эффектом.Как выяснилось в PostgreSQL, вы можете использовать
PREPARE
операторы так же, как и в языке сценариев. К сожалению, вы все еще не можете использовать?
, но можете использовать$n
обозначения.Используя приведенный выше пример:
PREPARE foo(text,text,text) AS SELECT * FROM foobar WHERE foo = $1 AND bar = $2 OR baz = $3 ; EXECUTE foo('foo','bar','baz'); DEALLOCATE foo;
источник
foo
он занят, а другойPREPARE
должен иметь другое имя, пока текущий сеанс не закрыт. Если вы играете сPREPARE
вpsql
это трудно придумать каждый раз новое имя иDEALLOCATE
может помочь с этим =)В psql есть механизм через
\set name val
команда, которая должна быть связана с параметром
-v name=val
командной строки. Цитирование болезненно. В большинстве случаев проще поместить все содержание запроса в оболочку here-document.редактировать
ой, я должен был сказать
-v
вместо-P
(что касается параметров форматирования) предыдущий ответ все правильно.источник
Вы также можете передать параметры в командной строке psql или из командного файла. Первые операторы собирают необходимые данные для подключения к вашей базе данных.
Последнее приглашение запрашивает значения ограничений, которые будут использоваться в предложении WHERE column IN (). Не забудьте заключать строки в одинарные кавычки и разделять их запятыми:
@echo off echo "Test for Passing Params to PGSQL" SET server=localhost SET /P server="Server [%server%]: " SET database=amedatamodel SET /P database="Database [%database%]: " SET port=5432 SET /P port="Port [%port%]: " SET username=postgres SET /P username="Username [%username%]: " SET /P bunos="Enter multiple constraint values for IN clause [%constraints%]: " ECHO you typed %constraints% PAUSE REM pause "C:\Program Files\PostgreSQL\9.0\bin\psql.exe" -h %server% -U %username% -d %database% -p %port% -e -v v1=%constraints% -f test.sql
Теперь в вашем файле кода SQL добавьте токен v1 в предложение WHERE или где-нибудь еще в SQL. Обратите внимание, что токены также могут использоваться в открытом операторе SQL, а не только в файле. Сохраните это как test.sql:
SELECT * FROM myTable WHERE NOT someColumn IN (:v1);
В Windows сохраните весь файл как пакетный файл DOS (.bat), сохраните test.sql в том же каталоге и запустите пакетный файл.
Спасибо Дэйву Пейджу из EnterpriseDB за оригинальный сценарий с подсказками.
источник
Казалось бы, то, что вы просите, нельзя сделать прямо из командной строки . Вам придется либо использовать определяемую пользователем функцию в plpgsql, либо вызывать запрос из языка сценариев (и последний подход немного упрощает предотвращение внедрения SQL).
источник
Я хотел бы предложить другой ответ, вдохновленный комментарием @ malcook (с использованием bash).
Эта опция может работать для вас, если вам нужно использовать переменные оболочки в вашем запросе при использовании
-c
флага . В частности, я хотел получить счетчик таблицы, имя которой было переменной оболочки (которую вы не можете передать напрямую при использовании-c
).Предположим, у вас есть переменная оболочки
Затем вы можете получить результаты, используя
psql -q -A -t -d databasename -c <<< echo "select count(*) from $TABLE_NAME;"
(
-q -A -t
просто распечатать получившееся число без дополнительного форматирования)Замечу, что
echo
в строке здесь (<<<
оператор) может не быть необходимости, я изначально думал, что цитаты сами по себе подойдут, может быть, кто-то сможет прояснить причину этого.источник
В итоге я использовал лучшую версию ответа @ vol7ron:
DO $$ BEGIN IF NOT EXISTS(SELECT 1 FROM pg_prepared_statements WHERE name = 'foo') THEN PREPARE foo(text,text,text) AS SELECT * FROM foobar WHERE foo = $1 AND bar = $2 OR baz = $3; END IF; END$$; EXECUTE foo('foo','bar','baz');
Таким образом, вы всегда можете выполнить его в таком порядке (запрос подготовлен, только если он еще не подготовлен), повторить выполнение и получить результат последнего запроса.
источник