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

मैंने कोशिश की कि - इसे स्क्रिप्ट में पुनः प्राप्त करने के लिए, मैं "SELECT current_setting ('pretend') INTO _result" कह रहा हूँ - कोई सफलता नहीं।
Jmoney38

जवाबों:


5

कड़ाई से बोलने पर, "plpgsql script" जैसी कोई चीज नहीं है - PL / pgSQL PostgreSQL की डिफ़ॉल्ट प्रक्रियात्मक भाषा है। यह या तो एक SQL स्क्रिप्ट या एक plpgsql फ़ंक्शन / प्रक्रिया है। आपका उदाहरण SQL स्क्रिप्ट को इंगित करता है।

आप इसके बजाय एक (सर्वर-साइड) plpgsql (या sql) फ़ंक्शन बना सकते हैं, जो किसी भी संख्या में तर्क लेता है। जब तक तर्क हैं यह बहुत सरल है values। यह थोड़ा और अधिक जटिल हो जाता है यदि तर्कों में पहचानकर्ता शामिल होते हैं। तो फिर तुम गतिशील एसक्यूएल और साथ PL / pgSQL का उपयोग करना होगा EXECUTE

PL / pgSQL पूर्व में डिफ़ॉल्ट रूप से PostgreSQL 9.0 या बाद में स्थापित है। आपको इसे Postgres 8.3 में प्रति डेटाबेस एक बार इंस्टॉल करना होगा, हालांकि:

CREATE LANGUGAGE plpgsql;

संस्करण की बात: आप PostgreSQL के वर्तमान संस्करण में अपग्रेड करने पर विचार करें । 2013 के अंत तक v8.3 बहुत पुराना हो चुका है।

चूंकि आपको लगता है कि एक तैयार एसक्यूएल स्क्रिप्ट है तो मैं एसक्यूएल फ़ंक्शन प्रदर्शित करूंगा। दो पूर्णांक तर्कों के साथ सरल डमी फ़ंक्शन:

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 से काफी अवगत हूं - यह स्क्रिप्ट जिसका मैं जिक्र कर रहा हूं वह एक ऐसी फाइल है जिसमें कई कार्य हैं। सी-उन्मुख प्रोग्रामिंग के अर्थ में मेरा "मुख्य" फ़ंक्शन है। स्क्रिप्ट / फ़ाइल के भीतर अंतिम 2 पंक्तियाँ 1) "मुख्य" फ़ंक्शन को कॉल करती हैं और फिर 2) फ़ंक्शन को छोड़ देती हैं। तो, इस सेटअप में, मेरे पास अनिवार्य रूप से एक स्व-निहित स्क्रिप्ट है जिसे काम करने के लिए चलाया जा सकता है (psql -f)। मैं psql -c के माध्यम से "एप्लिकेशन आर्ग्स" के साथ एक फ़ंक्शन को कॉल करने के बारे में आपकी बात पसंद करता हूं। मैं शायद उस रास्ते पर जाऊंगा, क्योंकि मैं पोस्टग्रैस.कॉन्फ़ फ़ाइल में मान जोड़ने का मार्ग नहीं जा सकता।
जमुनी38

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_settingऔर SETया setval, आपको postgresql.confविकल्प जोड़ने के लिए एक पंक्ति को जोड़ना होगा।


2

मेरे अनुभव से, एक plpgsql घोषणा के अंदर एक psql चर dereffing के रूप में इस तरह के निर्माण में बिलिन या DO BEGIN एक वाक्यविन्यास त्रुटि में परिणाम:

/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=#

क्रिएट फंक्शन या डीओ घोषणाओं में अतिरिक्त psql वैरिएबल का उपयोग करने के लिए आप प्रति चर के लिए एक कॉलम बना सकते हैं।


0

यह बहुत सुंदर नहीं है, लेकिन यह काम करता है (स्यूडोकोड):

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

0

यह दृष्टिकोण आपको एनवी वर्सेस का फुल रन-टाइम रिज़ॉल्यूशन प्रदान करेगा ... इसलिए जैसे ही आपकी स्क्रिप्ट हाथ से पहले सेट हो जाएगी सभी शेल वैरिएबल यह काम करेंगे ( अलग-अलग डीबीएस और होस्ट के खिलाफ हजारों बार चला गया है ):

    -- 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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.