psql에 인수 전달


10

Postgres 8.3에서 plpgsql 스크립트를 실행 중입니다. psql을 통해이 스크립트에 인수를 전달하고 싶습니다. 현재 다음과 같은 스크립트를 실행 중입니다.

psql -d database -u user -f update_file.sql 

내가 건너 온 이 링크 PGOPTIONS 환경 변수를 설명합니다,하지만 "사용자 정의"인수 작업을하지 않습니다. 즉, 설정이 postgres.conf 파일에 없기 때문에 오류가 발생합니다.

-bash-3.2$ export PGOPTIONS='--pretend=true'
-bash-3.2$ psql -d my_db -f update_database.sql
psql: FATAL:  unrecognized configuration parameter "pretend"

다른 아이디어가 있습니까? 이상적으로는 환경 변수를 피하고 싶습니다 ...


-vpsql 의 주장을 찾고 있다고 생각합니다 .
dezso 2016 년

나는 그것을 시도했다-스크립트에서 그것을 검색하기 위해, 나는 "SELECT current_setting ( 'pretend') INTO _result"라고 부르고있다-성공하지 못했습니다.
Jmoney38

답변:


5

엄밀히 말하면 "plpgsql 스크립트"와 같은 것은 없습니다. PL / pgSQL은 PostgreSQL의 기본 절차 언어입니다. SQL 스크립트 또는 plpgsql 함수 / 프로 시저입니다. 귀하의 예는 SQL 스크립트를 나타내는 것 같습니다.

대신 여러 인수를 사용하는 (서버 측) plpgsql (또는 sql) 함수 를 만들 수 있습니다 . 인수가있는 한 매우 간단 values합니다. 인수에 식별자가 포함되어 있으면 조금 더 복잡해집니다. 그런 다음 동적 SQL 및와 함께 PL / pgSQL을 사용해야 EXECUTE합니다.

PL / pgSQL은 PostgreSQL 9.0 이상에서 기본적으로 사전 설치됩니다. 그러나 Postgres 8.3의 데이터베이스마다 한 번씩 설치해야합니다.

CREATE LANGUGAGE plpgsql;

버전에 대하여 : 현재 버전의 PostgreSQL로 업그레이드 하는 것을 고려해야 합니다. v8.3은 2013 년 초에 수명이 다한 지금 매우 오래되었습니다.

준비된 SQL 스크립트가있는 것 같으므로 SQL 함수를 보여 드리겠습니다. 두 개의 정수 인수가있는 간단한 더미 함수 :

CREATE OR REPLACE FUNCTION func(int, int)
    LANGUAGE sql RETURNS void AS 
$func$
    UPDATE tbl1 SET col1 = $1 WHERE id = $2;
    UPDATE tbl2 SET col1 = $1 WHERE id = $2;
$func$;

dba.SE 또는 SO 에서 plpgsql에 대한보다 정교한 예제를 찾을 수 있습니다 .

이 함수를 호출하고 쉘 스크립트에서 매개 변수를 전달할 수 있습니다. 정수 매개 변수에 입력 매개 변수를 사용하는 쉘 스크립트 호출의 기본 예제 (필요한 값 주위에 작은 따옴표가 없음) :

psql mydb -c "SELECT func($1, $2)"

또는 모든 데이터 유형이있는 경우 :

psql mydb -c "SELECT func2('$1'::text, '$2'::numeric)"

-c하나의 명령 문자열을 실행 다음 종료합니다. 매뉴얼에서 psql의 명령 행 인수에 대한 추가 정보 .


응답 주셔서 감사합니다-나는 실제로 plpgsql에 대해 잘 알고 있습니다-내가 언급하는이 스크립트는 수많은 기능을 포함하는 파일입니다. C 지향 프로그래밍의 의미에서 "주요"기능이 있습니다. 스크립트 / 파일 내의 마지막 두 줄은 1) "main"함수를 호출 한 다음 2) 함수를 삭제하는 것입니다. 따라서이 설정에는 기본적으로 작업을 수행하기 위해 실행할 수있는 자체 포함 스크립트가 있습니다 (psql -f). psql -c를 통해 "application args"로 함수를 호출하는 것에 대한 요점을 좋아합니다. postgres.conf 파일에 값을 추가하는 경로로는 갈 수 없기 때문에 아마도 해당 경로로 갈 것입니다.
Jmoney38

5

다른 기능을 추가하려면 -v... 견적을 추가하려는 경우 명령 행에 추가하십시오.

psql -v action="'drop'"

그러면 다음 코드가 실행됩니다.

select * where :action;

와 동일

select * where 'drop';

4

시도 -v:

$ psql -U postgres -v something=\'blah-blah\'
psql (9.1.3)
Type "help" for help.

postgres=# select :something;
 ?column?
----------
 blah-blah
(1 row)

당신이 사용하려는 경우 current_settingSET또는 setval, 당신은 할 수있는 행에 추가 할 postgresql.conf수있는 옵션을 추가 할 수 있습니다.


2

내 경험상 CREATE FUNCTION BEGIN 또는 DO BEGIN과 같은 plpgsql 선언 내에서 psql 변수를 파생하면 구문 오류가 발생합니다.

/tmp $ psql -U jmindek -v action=drop
psql (9.3.4)
Type "help" for help.

jmindek=# select :'action';
 ?column? 
----------
 drop
(1 row)

jmindek=# DO $$ BEGIN RAISE INFO 'The value in variable action is (%)',:x; END $$;     
ERROR:  syntax error at or near ":"
LINE 1: ... RAISE INFO 'The value in variable action is (%)',:x; END $$...

내 솔루션은 단일 열이있는 임시 테이블을 만들고 그 값을 저장하는 것입니다. 이 임시 테이블은 plpgsql을 통해 액세스 할 수 있으므로 DO 블록에서 사용되는 psql 변수를 전달할 수 있습니다.

 ~ $ psql -v action=drop
psql (9.3.4)
Type "help" for help.

jmindek=# create temporary table actions (type text);                                                             CREATE TABLE
jmindek=# insert into actions values (:'action');                                                                 INSERT 0 1
jmindek=# do $$                                                                                                   declare                                                                                                            action_type text := null;                                                                                        begin                                                                                                               select type from actions into action_type;                                                                        raise info 'Hello, the action is (%)',action_type;                                                              end $$;
INFO:  Hello, the action is (drop)
DO
jmindek=#

CREATE FUNCTION 또는 DO 선언에서 추가 psql 변수를 사용하려면 필요한 변수마다 열을 작성할 수 있습니다.


0

이것은 매우 우아하지는 않지만 작동합니다 (의사 코드).

cat <<EOF
   UPDATE tablename SET field=$arg1 WHERE field = $arg2;
EOF | psql database

0

이 접근법은 env vars의 완전한 런타임 해상도를 제공합니다 ... 스크립트가 미리 모든 쉘 변수를 미리 설정하자마자 작동합니다 ( 다른 db 및 호스트에 대해 수천 번 실행되었습니다 ).

    -- start run.sh

       # 01 create / modify the app user
       sql_script="$pgsql_scripts_dir/01.create-qto-app-user.pgsql"
       PGPASSWORD="${postgres_db_useradmin_pw:-}" psql -q -t -X -w -U "${postgres_db_useradmin:-}" \
          -h $postgres_db_host -p $postgres_db_port \
          -v ON_ERROR_STOP=1 \
          -v postgres_db_user_pw="${postgres_db_user_pw:-}" \
          -v postgres_db_name="${postgres_db_name:-}" \
          -f "$sql_script" "${postgres_db_name:-}" > "$tmp_log_file" 2>&1
       ret=$?
       cat "$tmp_log_file" ; cat "$tmp_log_file" >> $log_file # show it and save it
       test $ret -ne 0 && sleep 3
       test $ret -ne 0 && doExit 1 "pid: $$ psql ret $ret - failed to run sql_script: $sql_script !!!"
    -- stop run.sh

    -- start fun.sql
            DO
            $do$
            BEGIN
               IF NOT EXISTS (
                  SELECT
                  FROM   pg_catalog.pg_roles
                  WHERE  rolname = 'usrqtoapp') THEN
                     CREATE ROLE usrqtoapp WITH PASSWORD ':postgres_db_user_pw' LOGIN ;
               END IF;
            END
            $do$;
            ALTER ROLE usrqtoapp WITH PASSWORD  :'postgres_db_user_pw' LOGIN ;

    -- eof run.sql
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.