[postgresql] PostgreSQL : 명령 줄에서 매개 변수를 전달하는 방법은 무엇입니까?

?자리 표시자를 사용하는 스크립트에 다소 자세한 쿼리가 있습니다. 이 동일한 쿼리를 psql 명령 줄 (스크립트 외부)에서 직접 테스트하고 싶었습니다. 들어가서 모든 것을 ?실제 값으로 바꾸는 것을 피하고 대신 쿼리 후에 인수를 전달하고 싶습니다.

예:

SELECT  *
FROM    foobar
WHERE   foo = ?
   AND  bar = ?
    OR  baz = ?  ;

다음과 같은 것을 찾고 있습니다.

%> {select * from foobar where foo=? and bar=? or baz=? , 'foo','bar','baz' };



답변

-v 구문을 사용할 수 있습니다.

psql -v v1=12  -v v2="'Hello World'" -v v3="'2010-11-12'"

그런 다음 SQL의 변수를 : v1, : v2 등으로 참조하십시오.

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;


답변

psql에는 다음을 통한 메커니즘이 있습니다.

\set name val

명령 -v name=val줄 옵션에 연결되어 있어야합니다 . 인용은 고통 스럽습니다. 대부분의 경우 전체 쿼리 고기를 쉘 here-document 안에 넣는 것이 더 쉽습니다.

편집하다

죄송합니다. (포맷 옵션을위한) -v대신 -P이전 답변이 제대로 되었다고 말 했어야 했습니다.


답변

psql 명령 줄 또는 배치 파일에서 매개 변수를 전달할 수도 있습니다. 첫 번째 명령문은 데이터베이스 연결에 필요한 세부 정보를 수집합니다.

마지막 프롬프트는 WHERE 열 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 코드 파일에서 WHERE 절 또는 SQL의 다른 곳에 v1 토큰을 추가합니다. 토큰은 파일뿐만 아니라 열린 SQL 문에서도 사용할 수 있습니다. 이것을 test.sql로 저장하십시오.

SELECT * FROM myTable
WHERE NOT someColumn IN (:v1);

Windows에서는 전체 파일을 DOS BATch 파일 (.bat)로 저장하고 test.sql을 동일한 디렉토리에 저장 한 다음 배치 파일을 실행합니다.

원본 프롬프트 스크립트에 대해 EnterpriseDB의 Dave Page에게 감사드립니다.


답변

당신이 요청한 것은 명령 줄에서 직접 수행 할 수없는 것처럼 보입니다 . plpgsql에서 사용자 정의 함수를 사용하거나 스크립팅 언어에서 쿼리를 호출해야합니다 (후자의 접근 방식을 사용하면 SQL 삽입을 더 쉽게 피할 수 있습니다).


답변

@malcook의 의견 (bash 사용)에서 영감을 얻은 또 다른 답변을 제공하고 싶습니다.

이 옵션은 플래그사용할 때 쿼리 내에서 쉘 변수-c사용해야하는 경우에 적합합니다 . 특히, 이름이 쉘 변수 (사용할 때 직접 전달할 수없는) 인 테이블의 개수를 얻고 싶었습니다.-c .

쉘 변수가 있다고 가정하십시오.

$TABLE_NAME='users'

그런 다음 사용하여 결과를 얻을 수 있습니다.

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');

이렇게하면 항상이 순서 (아직 준비되지 않은 경우에만 준비된 쿼리)로 실행하고 실행을 반복하고 마지막 쿼리에서 결과를 가져올 수 있습니다.