psql에서 스크립트 변수를 어떻게 사용합니까?
MS SQL Server에서 사용자 지정 가능한 변수를 사용하기 위해 스크립트를 만듭니다.
DECLARE @somevariable int
SELECT @somevariable = -1
INSERT INTO foo VALUES ( @somevariable )
▁value▁the다니합변▁i경▁change'▁then의 값을 변경하겠습니다.@somevariable
특정 상황에서 내가 원하는 값에 따라 런타임에.대본의 맨 위에 있기 때문에 쉽게 보고 기억할 수 있습니다.
PostgrePostgre에서 하려면 어떻게 해야 ?psql
?
postgres 변수는 \set 명령을 통해 생성됩니다(예: ...).
\set myvariable value
그런 다음 예를 들어 ...로 대체할 수 있습니다.
SELECT * FROM :myvariable.table1;
아니면...
SELECT * FROM table1 WHERE :myvariable IS NULL;
편집: psql 9.1 기준으로 변수는 다음과 같이 따옴표로 확장할 수 있습니다.
\set myvariable value
SELECT * FROM table1 WHERE column1 = :'myvariable';
이전 버전의 psql 클라이언트의 경우:
변수를 조건부 문자열 조회의 값으로 사용하려는 경우(예:
SELECT * FROM table1 WHERE column1 = ':myvariable';
변수 자체에 따옴표를 포함해야 합니다. 위에서는 작동하지 않습니다.대신 변수를 다음과 같이 정의합니다.
\set myvariable 'value'
하지만 저처럼 기존 변수에서 문자열을 만들고자 하는 상황에 부딪혔다면, 저는 그 속임수가 이것이라는 것을 알게 되었습니다.
\set quoted_myvariable '\'' :myvariable '\''
이제 같은 문자열의 따옴표가 붙은 변수와 따옴표가 없는 변수가 모두 있습니다!그리고 당신은 이와 같은 것을 할 수 있습니다.
INSERT INTO :myvariable.table1 SELECT * FROM table2 WHERE column1 = :quoted_myvariable;
PSQL 변수에 대한 마지막 단어:
SQL 문에서 작은 따옴표로 묶어도 확장되지 않습니다.따라서 이것은 작동하지 않습니다.
SELECT * FROM foo WHERE bar = ':myvariable'
SQL 문에서 문자열 리터럴로 확장하려면 변수 집합에 따옴표를 포함해야 합니다.그러나 변수 값은 이미 따옴표로 묶어야 하므로 두 번째 따옴표 집합이 필요하고 내부 집합은 이스케이프되어야 합니다.따라서 다음이 필요합니다.
\set myvariable '\'somestring\'' SELECT * FROM foo WHERE bar = :myvariable
편집: Postgre로 시작SQL 9.1은 다음과 같이 작성할 수 있습니다.
\set myvariable somestring SELECT * FROM foo WHERE bar = :'myvariable'
WITH 절을 사용해 볼 수 있습니다.
WITH vars AS (SELECT 42 AS answer, 3.14 AS appr_pi)
SELECT t.*, vars.answer, t.radius*vars.appr_pi
FROM table AS t, vars;
특의 경우히의 경우.psql
합격할 수 있습니다psql
를 사용할 수 . 를 전달할 때는 " 행의변사수있다습니할용명수도령다▁variables▁from니▁them있▁pass"를 할 수 있습니다.-v
다음은 사용 예입니다.
$ psql -v filepath=/path/to/my/directory/mydatafile.data regress
regress=> SELECT :'filepath';
?column?
---------------------------------------
/path/to/my/directory/mydatafile.data
(1 row)
콜론이 따옴표로 묶이지 않은 다음 변수 이름 자체가 따옴표로 묶입니다.이상한 구문인 거 알아요이것은 psql에서만 작동하고 PgAdmin-III에서는 작동하지 않습니다.
psql에서 입력 ▁this▁a▁usessay▁can다▁process를 사용하는 함수를 정의 수 없습니다.:'filepath'
은 그고그가기대니다합를치리▁of▁the▁value▁and▁expect다니기대.:'filepath'
세션 간에 변경할 수 있습니다.함수가 정의될 때 한 번 대체되고 그 이후에는 상수가 됩니다.스크립팅에는 유용하지만 런타임에는 사용할 수 없습니다.
FWIW, 실제 문제는 \set 명령어 끝에 세미콜론을 포함했다는 것입니다.
\set owner_password '비밀번호';
세미콜론은 변수의 실제 문자로 해석되었습니다.
\filename:owner_password 비밀번호;
그래서 제가 그것을 사용하려고 했을 때:
CREATE ROLE myrole 로그인 암호화되지 않은 비밀번호 :owner_password 'infinity'까지 유효한 상속 작성자 역할이 없습니다.
...알겠습니다.
CREATE ROLE myrole 암호화되지 않은 로그인 비밀번호, 'infinity'까지 유효한 상속 CREATE B CREATEROLE이 없습니다.
이는 리터럴 주위에 따옴표를 설정하는 데 실패했을 뿐만 아니라 명령을 두 부분으로 나눕니다(두 번째 부분은 "NO INHERIT"로 시작했기 때문에 유효하지 않습니다.
이 이야기의 교훈: PostgreSQL "변수"는 실제 텍스트 확장에 사용되는 매크로이지 실제 값이 아닙니다.그게 도움이 될 거라고 확신하지만, 처음에는 까다롭습니다.
postgres(버전 9.0 이후)는 지원되는 서버 측 스크립트 언어에서 익명 블록을 허용합니다.
DO '
DECLARE somevariable int = -1;
BEGIN
INSERT INTO foo VALUES ( somevariable );
END
' ;
http://www.postgresql.org/docs/current/static/sql-do.html
모든 것이 문자열 내부에 있으므로 대체할 외부 문자열 변수를 이스케이프하고 두 번 따옴표로 묶어야 합니다.대신 $ 견적을 사용하면 SQL 주입을 완벽하게 방지할 수 없습니다.
SQL proc 언어가 아닌 PL/pgSQL과 같은 절차 언어 중 하나를 사용해야 합니다.PL/pgSQL에서는 SQL 문에서 바로 변수를 사용할 수 있습니다.단일 따옴표의 경우 따옴표 리터럴 함수를 사용할 수 있습니다.
저는 그것을 임시 테이블로 해결했습니다.
CREATE TEMP TABLE temp_session_variables (
"sessionSalt" TEXT
);
INSERT INTO temp_session_variables ("sessionSalt") VALUES (current_timestamp || RANDOM()::TEXT);
이렇게 하면 세션에 고유한 여러 쿼리에 사용할 수 있는 "변수"가 있습니다.동일한 사용자 이름을 가진 사용자를 가져올 경우 충돌이 발생하지 않으면서 고유한 "사용자 이름"을 생성하기 위해 필요했습니다.
또 다른 접근 방식은 Postgre를 사용하는 것입니다.변수를 생성하는 SQL GUC 메커니즘입니다.자세한 내용과 예제는 이 이전 답변을 참조하십시오.
를 "GUC"로 합니다.postgresql.conf
시 할 때 다런변값다니경합을에타임음▁its▁at▁then다▁changeSET
를 사용하여 .current_setting(...)
.
일반적인 용도로는 권장하지 않지만, 포스터가 트리거 및 기능에 응용 프로그램 수준의 사용자 이름을 제공하는 방법을 원했던 링크된 질문에 언급된 경우와 같은 좁은 경우에 유용할 수 있습니다.
저는 이 질문과 대답이 매우 유용하면서도 혼란스럽다는 것을 알게 되었습니다.인용된 변수를 작동시키는 데 많은 어려움을 겪었기 때문에 다음과 같이 작동했습니다.
\set deployment_user username -- username
\set deployment_pass '\'string_password\''
ALTER USER :deployment_user WITH PASSWORD :deployment_pass;
이렇게 하면 변수를 하나의 문에 정의할 수 있습니다.사용 시 변수에 작은 따옴표가 포함됩니다.
참고! 인용된 변수 뒤에 주석을 달았을 때 다른 답변에서 몇 가지 방법을 시도했을 때 변수의 일부로 빨려 들어갔습니다.그것은 한동안 저를 정말로 망치게 했습니다.이 방법을 사용하면 설명이 예상대로 처리되는 것 같습니다.
저는 그 기능이 정말 그립습니다.비슷한 것을 달성하는 유일한 방법은 기능을 사용하는 것입니다.
두 가지 방법으로 사용해 왔습니다.
- $_SHARED 변수를 사용하는 perl 함수
- 변수를 표에 저장
Perl 버전:
CREATE FUNCTION var(name text, val text) RETURNS void AS $$
$_SHARED{$_[0]} = $_[1];
$$ LANGUAGE plperl;
CREATE FUNCTION var(name text) RETURNS text AS $$
return $_SHARED{$_[0]};
$$ LANGUAGE plperl;
테이블 버전:
CREATE TABLE var (
sess bigint NOT NULL,
key varchar NOT NULL,
val varchar,
CONSTRAINT var_pkey PRIMARY KEY (sess, key)
);
CREATE FUNCTION var(key varchar, val anyelement) RETURNS void AS $$
DELETE FROM var WHERE sess = pg_backend_pid() AND key = $1;
INSERT INTO var (sess, key, val) VALUES (sessid(), $1, $2::varchar);
$$ LANGUAGE 'sql';
CREATE FUNCTION var(varname varchar) RETURNS varchar AS $$
SELECT val FROM var WHERE sess = pg_backend_pid() AND key = $1;
$$ LANGUAGE 'sql';
주의:
- plperlu는 perl보다 빠릅니다.
- pg_start_pid는 최상의 세션 식별이 아닙니다. pg_stat_activity에서 backend_start와 결합된 pid를 사용하는 것을 고려해 보십시오.
- 이 테이블 버전은 또한 좋지 않습니다. 이 테이블 버전은 가끔 위의 항목을 지워야 하기 때문입니다(현재 작업 중인 세션 변수는 삭제하지 마십시오).
변수:psql
정수를 선언하려면 정수를 입력한 다음 캐리지 리턴을 수행한 다음 세미콜론으로 문을 종료해야 합니다.관찰:
정수 변수를 선언한다고 가정합니다.my_var
표에 삽입합니다.test
:
예제 표test
:
thedatabase=# \d test;
Table "public.test"
Column | Type | Modifiers
--------+---------+---------------------------------------------------
id | integer | not null default nextval('test_id_seq'::regclass)
Indexes:
"test_pkey" PRIMARY KEY, btree (id)
분명히, 이 표에는 아직 아무것도 없습니다.
thedatabase=# select * from test;
id
----
(0 rows)
변수를 선언합니다.세미콜론이 다음 줄에 어떻게 있는지 주목하세요!
thedatabase=# \set my_var 999
thedatabase=# ;
이제 삽입할 수 있습니다.우리는 이 이상한 것을 사용해야 합니다.":''
구문 보기:
thedatabase=# insert into test(id) values (:'my_var');
INSERT 0 1
효과가 있었어요!
thedatabase=# select * from test;
id
-----
999
(1 row)
설명:
그럼... 다음 줄에 세미콜론이 없으면 어떻게 될까요?변수?확인:
선언합니다my_var
새 노선 없이
thedatabase=# \set my_var 999;
선택합니다.my_var
.
thedatabase=# select :'my_var';
?column?
----------
999;
(1 row)
그게 WTF야?정수가 아니라 문자열입니다. 999;
!
thedatabase=# select 999;
?column?
----------
999
(1 row)
이에 대한 새로운 해결책을 다른 스레드에 게시했습니다.
테이블을 사용하여 변수를 저장하며 언제든지 업데이트할 수 있습니다.정적 불변 게터 함수는 테이블 업데이트에 의해 트리거되어 동적으로 생성됩니다(다른 함수에 의해).훌륭한 테이블 스토리지와 더불어 불변의 게터의 엄청나게 빠른 속도를 얻을 수 있습니다.
언급URL : https://stackoverflow.com/questions/36959/how-do-you-use-script-variables-in-psql
'source' 카테고리의 다른 글
'날짜 시간'이 '없음'인지 확인할 수 없는 이유는 무엇입니까? (0) | 2023.06.04 |
---|---|
로컬 Git 저장소에서 원격 Git 저장소를 만드는 방법은 무엇입니까? (0) | 2023.06.04 |
Excel Interop으로 기존 Excel 파일을 저장/덮어쓰는 방법 - C# (0) | 2023.06.04 |
텍스트 편집 외부를 클릭한 후 안드로이드에서 소프트 키보드를 숨기는 방법은 무엇입니까? (0) | 2023.06.04 |
MongoDB.service가 결과 종료 코드와 함께 실패했습니다. (0) | 2023.05.25 |