आप psql में स्क्रिप्ट चर का उपयोग कैसे करते हैं?


133

MS SQL सर्वर में, मैं अनुकूलन योग्य चर का उपयोग करने के लिए अपनी स्क्रिप्ट बनाता हूं:

DECLARE @somevariable int  
SELECT @somevariable = -1

INSERT INTO foo VALUES ( @somevariable )

फिर मैं @somevariableरनटाइम के मूल्य को बदल दूंगा , जो उस स्थिति के आधार पर मैं चाहता हूं कि मैं विशेष स्थिति में चाहता हूं। चूंकि यह स्क्रिप्ट के शीर्ष पर है इसलिए इसे देखना और याद रखना आसान है।

मैं PostgreSQL क्लाइंट के साथ कैसे करूं psql?


5
FWIW, \ सेट ऑपरेटर pqql बैच भाषा के लिए नहीं, psql कमांड-लाइन टूल से संबंधित प्रतीत होता है। मै गलत हो सकता हूँ।
डेनियल यांकोव्स्की

1
Postgres के किस संस्करण पर आप हैं?
कुबेरचुन

जवाबों:


180

उदाहरण के लिए पोस्टग्रेज वैरिएबल को \ सेट कमांड के माध्यम से बनाया जाता है ...

\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;

66
\setकेवल psqlउपकरण के लिए है, आप इसे संग्रहीत प्रक्रियाओं में उपयोग नहीं कर सकते हैं!
सोरिन

6
@SorinSbarnea ओपी ने स्क्रिप्ट के बारे में पूछा , प्रक्रिया
डैनियल सेरोडियो

35
यह उत्तर भ्रमित करने वाले अंदाज में PostgreSQL कमांड के साथ psqlमेटा-कमांड \setको मिलाता है ।
इरविन ब्रांडस्टैटर

20
Postgresql 9.1 के रूप में, psql में अब आप इसका उपयोग कर सकते हैं: 'चर' को इसे आपके लिए एक मान के रूप में ठीक से उद्धृत किया गया है, या: "चर" को पहचानकर्ता के रूप में उपयोग करने के लिए।
हिट्सन

9
\set myvariable 'value'करता नहीं वेरिएबल के अंदर किसी भी बोली, क्या इस उत्तर का कहना है के विपरीत शामिल हैं। जब संदेह हो, तो \echo :myvariableकिसी भी क्वेरी के स्वतंत्र रूप से मूल्य प्रदर्शित करने के लिए psql के भीतर का उपयोग करें ।
डैनियल वेत्रे

61

PSQL चर पर एक अंतिम शब्द:

  1. यदि आप उन्हें SQL कथन में एकल उद्धरण में संलग्न करते हैं, तो उनका विस्तार नहीं होता है। इस प्रकार यह काम नहीं करता है:

    SELECT * FROM foo WHERE bar = ':myvariable'
  2. SQL स्टेटमेंट में एक स्ट्रिंग शाब्दिक का विस्तार करने के लिए, आपको चर सेट में उद्धरण शामिल करना होगा। हालांकि, चर मूल्य को पहले ही उद्धरणों में संलग्न किया जाना है, जिसका अर्थ है कि आपको उद्धरण के दूसरे सेट की आवश्यकता है , और आंतरिक सेट से बचना होगा। इस प्रकार आपको आवश्यकता है:

    \set myvariable '\'somestring\''  
    SELECT * FROM foo WHERE bar = :myvariable

    संपादित करें : PostgreSQL 9.1 के साथ शुरू, आप इसके बजाय लिख सकते हैं:

    \set myvariable somestring
    SELECT * FROM foo WHERE bar = :'myvariable'

12
चीयर्स:'myvariable'
एंडोमर

ठीक वही जो मेरे द्वारा खोजा जा रहा था!
केनिस्टवर्ड

47

आप एक क्लॉज़ के साथ उपयोग करने का प्रयास कर सकते हैं ।

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;

यह तरीका ज्यादातर सुविधाजनक है जब आप अपनी क्वेरी में कुछ बार समान गणना वाले मूल्यों का उपयोग कर रहे हैं।
स्कॉरस

2
ब्रायस की रिपोर्ट के विपरीत, यह मेरे लिए ठीक काम करता है। CREATE TABLE test (name VARCHAR, age INT); INSERT INTO test (name, age) VALUES ('Jack', 21), ('Jill', 20); WITH vars AS (SELECT N'Jack' AS name, 21 AS age) SELECT test.* FROM test, vars WHERE test.name = vars.name and test.age = vars.age; उम्मीद के मुताबिक़, जैक और जैक की उम्र।
यहोशू

2
बहुत सारे उपयोगों के लिए, विशेष रूप से पायथन फ्लास्क जैसे एक वेब एप्लिकेशन फ्रेमवर्क के संदर्भ में, यह एकल क्वेरी के भीतर जटिल गणना मूल्यों का पुन: उपयोग करने के लिए सबसे अच्छा समाधान है।
विल

1
क्या कोई सुझाव दे सकता है कि यह एक प्रविष्टि में कैसे काम कर सकता है?
स्टूपकिड

@Stoopkidcreate table t(x integer); insert into t(x) with sub as (select 999 as num) select num from sub; select * from t;
JL_SO

33

विशेष रूप से psql, आप psqlकमांड लाइन से चर भी पास कर सकते हैं; आप उन्हें पास कर सकते हैं -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 में इनपुट प्रसंस्करण के दौरान होता है, इसलिए आप एक ऐसे फ़ंक्शन को परिभाषित नहीं कर सकते हैं जो सत्र से सत्र तक परिवर्तन :'filepath'के मूल्य का उपयोग करता है और उम्मीद करता है :'filepath'। यह एक बार प्रतिस्थापित किया जाएगा, जब फ़ंक्शन परिभाषित होता है, और उसके बाद एक स्थिर होगा। यह स्क्रिप्टिंग के लिए उपयोगी है, लेकिन रनटाइम उपयोग के लिए नहीं।


psql चर, उदाहरण के लिए: 'filepath', आपने बताया: "ध्यान दें कि बृहदान्त्र अछूता है, फिर चर नाम अपने आप को उद्धृत करता है।" धन्यवाद! आप! मैंने पहले से ही अपने डेस्क में माथे के आकार के डेंट का एक गुच्छा रखा था, जो इस काम को करने की कोशिश कर रहा था, और आपने मुझे सिर्फ एक टन बचा लिया। वास्तव में मुझे कुछ स्क्रिप्टिंग के लिए जो चाहिए था।
जेसन

13

FWIW, असली समस्या यह थी कि मैंने अपने \ _ कमांड के अंत में एक अर्धविराम शामिल किया था:

\ सेट का मालिक_पासवर्ड 'क्रॉसवर्ड';

अर्धवृत्त की व्याख्या चर में एक वास्तविक चरित्र के रूप में की गई थी:

\ echo: owner_password thepassword;

इसलिए जब मैंने इसका उपयोग करने की कोशिश की:

क्री रोले मैरोले लॉग यूनिनेटेड पास्कवर्ड: owner_password NOINHERIT CREATEDB CREATEROLE VALID UNTIL 'infinity';

...मुझे यह मिल गया:

बनाएँ रोली मैरोल लॉग UNENCRYPTED पासवर्ड क्रॉसवर्ड; NOINHERIT CREATEBOL CREATEROLE वैध UNTIL 'अनंत';

यह न केवल शाब्दिक के आसपास उद्धरण सेट करने में विफल रहा, बल्कि कमांड को 2 भागों में विभाजित करता है (जिनमें से दूसरा अमान्य था क्योंकि यह "NOINHERIT" के साथ शुरू हुआ था)।

इस कहानी का नैतिक: PostgreSQL "चर" वास्तव में पाठ के विस्तार में प्रयुक्त मैक्रोज़ हैं, न कि सच्चे मूल्य। मुझे यकीन है कि यह काम आता है, लेकिन यह पहली बार में मुश्किल है।


12

आपको पीएल / पीजीक्यूएल जैसी प्रक्रियात्मक भाषाओं में से एक का उपयोग करने की आवश्यकता है न कि एसक्यूएल खरीद भाषा। PL / pgSQL में आप SQL स्टेटमेंट में सही var का उपयोग कर सकते हैं। एकल उद्धरणों के लिए आप उद्धरण शाब्दिक फ़ंक्शन का उपयोग कर सकते हैं।


5
यह स्वयं पोस्टग्रेज में नहीं किया जा सकता है, लेकिन यह PSQL क्लाइंट एप्लिकेशन में किया जा सकता है।
फीलुमिनाती

1
plpgsql (अब) postgres (संस्करण 9.0 के बाद से) में इस्तेमाल किया जा सकता है) postgresql.org/docs/9.0/static/sql-do.html
Jasen

11

पोस्टग्रेज (संस्करण 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 इंजेक्शन के खिलाफ पूर्ण सुरक्षा नहीं देगा।


5

चर बनाने के लिए PostgreSQL GUC तंत्र का एक और तरीका है (ab)। विवरण और उदाहरण के लिए यह पूर्व उत्तर देखें ।

आप GUC को घोषित करते हैं postgresql.conf, फिर SETकमांड के साथ रनटाइम पर इसका मान बदलते हैं और इसके साथ इसका मूल्य प्राप्त करते हैं current_setting(...)

मैं इसे सामान्य उपयोग के लिए अनुशंसित नहीं करता हूं, लेकिन यह संकीर्ण प्रश्नों में उपयोगी हो सकता है जैसे कि लिंक किए गए प्रश्न में उल्लेख किया गया है, जहां पोस्टर ट्रिगर और फ़ंक्शन को एप्लिकेशन-स्तरीय उपयोगकर्ता नाम प्रदान करने का एक तरीका चाहता था।


4

मैंने इसे एक टेम्प टेबल के साथ हल किया।

CREATE TEMP TABLE temp_session_variables (
    "sessionSalt" TEXT
);
INSERT INTO temp_session_variables ("sessionSalt") VALUES (current_timestamp || RANDOM()::TEXT);

इस तरह, मेरे पास एक "चर" था जिसे मैं कई प्रश्नों पर उपयोग कर सकता था, जो सत्र के लिए अद्वितीय है। मुझे एक ही उपयोगकर्ता नाम के साथ उपयोगकर्ताओं को आयात करते समय टकराव नहीं होने पर भी अद्वितीय "उपयोगकर्ता नाम" उत्पन्न करने के लिए इसकी आवश्यकता थी।


यह हेइडी एसक्यूएल जैसे दृश्य उपकरण में काम करने का एकमात्र तरीका है।
अल्टेयर 7852 17

2

मुझे यह प्रश्न और उत्तर बेहद उपयोगी लगे, लेकिन भ्रामक भी। मुझे काम करने में बहुत परेशानी हो रही थी, इसलिए यहाँ काम करने का तरीका बताया गया है:

\set deployment_user username    -- username
\set deployment_pass '\'string_password\''
ALTER USER :deployment_user WITH PASSWORD :deployment_pass;

इस तरह आप एक स्टेटमेंट में वेरिएबल को डिफाइन कर सकते हैं। जब आप इसका उपयोग करते हैं, तो एकल उद्धरण को चर में एम्बेड किया जाएगा।

ध्यान दें! जब मैंने उद्धृत चर के बाद एक टिप्पणी लगाई तो इसे चर के हिस्से के रूप में चूसा गया जब मैंने अन्य उत्तरों में कुछ तरीकों की कोशिश की। यह वास्तव में मुझे थोड़ी देर के लिए खराब कर रहा था। इस पद्धति के साथ टिप्पणियों का व्यवहार किया जाना चाहिए जैसा कि आप अपेक्षा करते हैं।


\set deployment_pass 'string_password' ALTER USER :deployment_user WITH PASSWORD :'deployment_pass';
जैसन

\ सेट SQL नहीं है यह एक psql बिल्ट-इन कमांड sql कमेंट्स समर्थित नहीं हैं।
जैसन

2

मुझे वास्तव में वह सुविधा याद आती है। केवल समान तरीके से कुछ हासिल करने के लिए कार्यों का उपयोग करना है।

मैंने इसका दो तरह से उपयोग किया है:

  • perl फ़ंक्शन जो $ _SHARED चर का उपयोग करते हैं
  • तालिका में अपने चर स्टोर करें

पर्ल संस्करण:

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

टिप्पणियाँ:

  • प्लपर प्रति पर्ल की तुलना में तेज है
  • pg_backend_pid सर्वोत्तम सत्र पहचान नहीं है, pg_stat_activity से बैकएंड_स्टार्ट के साथ संयुक्त पीआईडी ​​का उपयोग करने पर विचार करें
  • यह तालिका संस्करण भी खराब है क्योंकि आपको यह स्पष्ट करना होगा कि यह कभी-कभार होता है (और वर्तमान में काम कर रहे सत्रों को हटाएं नहीं)

1

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)

ये क्या डब्ल्यूटीएफ है? यह पूर्णांक नहीं है , यह एक स्ट्रिंग है 999; !

thedatabase=# select 999;
 ?column? 
----------
      999
(1 row)

5
अर्धविराम आपके लिए अप्रत्याशित बातें करता है कारण यह है कि एक अर्धविराम एक SQL कथन को समाप्त करता है, लेकिन आप एक psql कमांड टाइप कर रहे हैं, \ SQL, जो SQL नहीं है और एक समाप्ति अर्धविराम नहीं लेता है। अगली पंक्ति में अर्धविराम लगाने से चोट नहीं लगेगी, लेकिन बिल्कुल कुछ भी नहीं है। यह एक खाली कथन है।
वोल्कर

1

मैंने इसके लिए एक और सूत्र पर एक नया समाधान पोस्ट किया है ।

यह चर को संग्रहीत करने के लिए एक तालिका का उपयोग करता है, और इसे किसी भी समय अपडेट किया जा सकता है। एक स्थिर अपरिवर्तनीय गेटर फ़ंक्शन को गतिशील रूप से (किसी अन्य फ़ंक्शन द्वारा) बनाया जाता है, जो आपकी तालिका के लिए अद्यतन द्वारा चालू होता है। आपको अच्छी टेबल स्टोरेज मिलती है, साथ ही एक अपरिवर्तनीय गेट्टर की धधकती तेज गति।

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