আপনি কীভাবে পিএসএলএল স্ক্রিপ্ট ভেরিয়েবল ব্যবহার করবেন?


133

এমএস এসকিউএল সার্ভারে আমি কাস্টমাইজেবল ভেরিয়েবলগুলি ব্যবহার করতে আমার স্ক্রিপ্টগুলি তৈরি করি:

DECLARE @somevariable int  
SELECT @somevariable = -1

INSERT INTO foo VALUES ( @somevariable )

আমি তখন @somevariableরানটাইমের সময়টির মানটি পরিবর্তন করব , বিশেষ পরিস্থিতিতে যে মানটিটি আমি চাই তার উপর নির্ভর করে। যেহেতু এটি স্ক্রিপ্টের শীর্ষে রয়েছে এটি দেখতে এবং মনে রাখা সহজ।

পোস্টগ্র্রেএসকিউএল ক্লায়েন্টের সাথে আমি কীভাবে এটি করব psql?


5
FWIW, \ সেট অপারেটরটি পিএএসকিএল কমান্ড-লাইন সরঞ্জামের সাথে সম্পর্কিত বলে মনে হয়, পি-এস-এস-এল ব্যাচ ভাষার সাথে নয়। আমার ভুল হতে পারে.
ড্যানিয়েল ইয়াঙ্কোভস্কি

1
আপনি পোস্টগ্রিসের কোন সংস্করণে আছেন?
কুবেরচাঁন

উত্তর:


180

পোস্টগ্রিজ ভেরিয়েবলগুলি \ set কমান্ডের মাধ্যমে তৈরি করা হয়, উদাহরণস্বরূপ ...

\set myvariable value

... এবং তারপরে প্রতিস্থাপন করা যেতে পারে, উদাহরণস্বরূপ, যেমন ...

SELECT * FROM :myvariable.table1;

... বা ...

SELECT * FROM table1 WHERE :myvariable IS NULL;

সম্পাদনা করুন: পিএসএইচএল ৯.১ অনুসারে, ভেরিয়েবলগুলি উদ্ধৃতি হিসাবে বাড়ানো যেতে পারে:

\set myvariable value 

SELECT * FROM table1 WHERE column1 = :'myvariable';

পিএসকিএল ক্লায়েন্টের পুরানো সংস্করণগুলিতে:

... আপনি যদি শর্তযুক্ত স্ট্রিং ক্যোয়ারিতে ভেরিয়েবলটিকে মান হিসাবে ব্যবহার করতে চান তবে যেমন ...

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সরঞ্জামের জন্য , আপনি এটি সঞ্চিত পদ্ধতিতে ব্যবহার করতে পারবেন না!
sorin

6
@ সোরিনসবার্নিয়া ওপিতে স্ক্রিপ্ট সম্পর্কে নয়, পদ্ধতি
ড্যানিয়েল সেরোদিও

35
এই উত্তরটি বিভ্রান্তিকর ফ্যাশনে পোস্টগ্রেএসকিউএল কমান্ডের সাথে psqlমেটা-কমান্ডগুলি মিশ্রিত করে \set
এরউইন ব্র্যান্ডসেটেটার

20
পোস্টগ্রেস্কএল ৯.১ অনুসারে, পিএসকিএলে আপনি এখন ব্যবহার করতে পারেন: 'ভেরিয়েবল' এটি সঠিকভাবে আপনার জন্য একটি মান হিসাবে উদ্ধৃত করা যেতে পারে, বা: "ভেরিয়েবল" এটি সনাক্তকারী হিসাবে ব্যবহার করতে।
হিটস্ক্যান

9
\set myvariable 'value'এই উত্তরটি যা বলছে তার বিপরীতে ভেরিয়েবলের ভিতরে কোনও উদ্ধৃতি অন্তর্ভুক্ত করে না । সন্দেহ হলে \echo :myvariable, কোনও প্রশ্নের জন্য স্বতন্ত্রভাবে মানটি প্রদর্শন করতে পিএসকিএল-এর মধ্যে ব্যবহার করুন ।
ড্যানিয়েল ভ্যারিটি

61

পিএসকিউএল ভেরিয়েবলের একটি চূড়ান্ত শব্দ:

  1. আপনি এসকিউএল বিবৃতিতে একক উদ্ধৃতিতে এগুলি বন্ধ করে রাখলে সেগুলি প্রসারিত হয় না। সুতরাং এটি কাজ করে না:

    SELECT * FROM foo WHERE bar = ':myvariable'
  2. একটি এসকিউএল বিবৃতিতে একটি স্ট্রিং আক্ষরিক প্রসারিত করতে, আপনাকে ভেরিয়েবল সেটে উদ্ধৃতিগুলি অন্তর্ভুক্ত করতে হবে। যাইহোক, ভেরিয়েবল মানটি ইতিমধ্যে উদ্ধৃতিতে আবদ্ধ থাকতে হবে, যার অর্থ আপনার উদ্ধৃতিগুলির একটি দ্বিতীয় সেট প্রয়োজন , এবং অভ্যন্তরীণ সেটটি এড়িয়ে যেতে হবে। সুতরাং আপনার প্রয়োজন:

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

    সম্পাদনা : পোস্টগ্র্যাসকিউএল 9.1 দিয়ে শুরু করে আপনি তার পরিবর্তে লিখতে পারেন:

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

12
চিয়ার্স:'myvariable'
অনাদোমার

ঠিক আমি খুঁজছেন ছিল কি!
কেনিসটওয়ার্ড

47

আপনি একটি 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;

আপনি যখন আপনার ক্যোয়ারিতে কয়েকবার একই গণিত মান ব্যবহার করছেন তখন এই উপায়টি বেশিরভাগ ক্ষেত্রে সুবিধাজনক।
স্কোয়ারাস

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
কেউ কীভাবে পরামর্শ দিতে পারে যে এটি কীভাবে একটি সন্নিবেশে কাজ করতে পারে?
স্টুপকিড

@ স্টুপিডcreate table t(x integer); insert into t(x) with sub as (select 999 as num) select num from sub; select * from t;
জেএল_এসও

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)

নোট করুন যে কোলনটি উদ্ধৃত নয়, তারপরে তার স্বতঃপ্রযুক্তিটির নামটি উদ্ধৃত করা হবে। অদ্ভুত বাক্য গঠন, আমি জানি। এটি কেবল পিএসকিএল-তে কাজ করে; এটি PgAdmin-III তে (বলুন) কাজ করবে না।

এই প্রতিস্থাপনটি পিএসকিএল-তে ইনপুট প্রসেসিংয়ের সময় ঘটে, সুতরাং আপনি কোনও ফাংশন সংজ্ঞা (বলতে) পারবেন না যা সেশন থেকে সেশনে পরিবর্তনের :'filepath'মান আশা করে :'filepath'to এটি একবারে প্রতিস্থাপিত হবে, যখন ফাংশনটি সংজ্ঞায়িত হবে, এবং তারপরে তার পরে স্থির থাকবে। এটি স্ক্রিপ্টিংয়ের জন্য দরকারী তবে রানটাইম ব্যবহারের জন্য নয়।


পিএসকিএল ভেরিয়েবল, উদাহরণস্বরূপ: 'ফাইলপথ', আপনি উল্লেখ করেছেন: "দ্রষ্টব্য যে কোলনটি অবতীর্ণ নয়, তারপরে তার নিজের নামটি উদ্ধৃত হয় able" ধন্যবাদ! আপনি! আমি ইতিমধ্যে আমার ডেস্কে কপাল আকৃতির একটি গুচ্ছ এই কাজটি করার চেষ্টা করেছি এবং আপনি আমাকে আরও একটি টন বাঁচিয়েছেন। কিছু স্ক্রিপ্টিংয়ের জন্য আমার ঠিক কী দরকার।
জেসন

13

এফডাব্লুআইডাব্লু, আসল সমস্যাটি হ'ল আমি আমার \ সেট কমান্ডের শেষে একটি সেমিকোলন অন্তর্ভুক্ত করেছি:

owner মালিক_প্যাসওয়ার্ড 'thepassword' সেট করুন;

সেমিকোলনটি ভেরিয়েবলের আসল চরিত্র হিসাবে ব্যাখ্যা করা হয়েছিল:

cho প্রতিধ্বনি: মালিক_প্যাসওয়ার্ড thepassword;

সুতরাং যখন আমি এটি ব্যবহার করার চেষ্টা করেছি:

ভূমিকা মাইরোল তৈরি করুন লগইন আনইনক্রিপটেড পাসওয়ার্ড: মালিক_প্যাসওয়ার্ড ননহিরিট ক্রিয়েটেড ক্রিয়েটারোলি ভ্যালিড অবধি 'অনন্ত';

...আমি এটা বুজেছি:

ভূমিকা মাইরোল তৈরি করুন লগইন আনইনক্রিপটেড পাসওয়ার্ড থিপ্যাসওয়ার্ড; ননহরিত ক্রিয়েটেড ক্রিয়েটারোল ভ্যালিড অবধি 'অনন্ত';

এটি কেবল আক্ষরিক চারপাশে উদ্ধৃতিগুলি সেট করতে ব্যর্থ হয়েছিল, তবে কমান্ডটি 2 ভাগে বিভক্ত করেছে (যার দ্বিতীয়টি অবৈধ ছিল এটি "NOINHERIT" দিয়ে শুরু হয়েছিল)।

এই গল্পটির নৈতিকতা: পোস্টগ্রিসএসকিউএল "ভেরিয়েবলগুলি" সত্যিকারের মান নয়, পাঠ্য প্রসারণে ব্যবহৃত ম্যাক্রোগুলি। আমি নিশ্চিত যে এটি কার্যকর হয়, তবে এটি প্রথমে জটিল।


12

আপনার পিএল / পিজিএসকিউএল এর মতো প্রসেসরিজ ভাষাগুলির একটি এসকিউএল প্রোক ভাষা নয় proc পিএল / পিজিএসকিউএল এ আপনি এসকিউএল স্টেটমেন্টগুলিতে ওয়ার্স ব্যবহার করতে পারেন। একক উদ্ধৃতি জন্য আপনি উদ্ধৃতি আক্ষরিক ফাংশন ব্যবহার করতে পারেন।


5
এটি পোস্টগ্রিসে নিজেই করা যায় না, তবে এটি পিএসকিউএল ক্লায়েন্ট অ্যাপ্লিকেশনটিতে করা যেতে পারে।
ফিলুমিনাতি

1
plpgsql (এখন) পোস্টগ্র্যাসে (9.0 সংস্করণ থেকে) ব্যবহৃত হতে পারে postgresql.org/docs/9.0/static/sql-do.html
জেসেন

11

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

সবকিছু যেমন একটি স্ট্রিংয়ের অভ্যন্তরে থাকে, বহিরাগত স্ট্রিং ভেরিয়েবলগুলি প্রতিস্থাপিত হওয়ার পরে এড়িয়ে চলতে হবে এবং দুবার উদ্ধৃতি দেওয়া দরকার। পরিবর্তে ডলারের উদ্ধৃতি ব্যবহার করা এসকিউএল ইঞ্জেকশনের বিরুদ্ধে সম্পূর্ণ সুরক্ষা দেবে না।


5

আর একটি পদ্ধতি হ'ল (আব) ভেরিয়েবলগুলি তৈরি করতে পোস্টগ্রেএসকিউএল জিইউসি প্রক্রিয়াটি ব্যবহার করুন। দেখুন এই পূর্বে উত্তরবিশদ এবং উদাহরণের জন্য ।

আপনি জিইউসিটিকে এর মধ্যে ঘোষণা করেন 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);

এইভাবে, আমার একাধিক প্রশ্নের উপর আমি একটি "পরিবর্তনশীল" ব্যবহার করতে পারি, এটি সেশনের জন্য অনন্য। একই ব্যবহারকারীর নামের সাথে ব্যবহারকারীদের আমদানি করা যদি সংঘর্ষের মুখোমুখি না হয় তখনও অনন্য "ব্যবহারকারীর নাম" তৈরি করতে আমার এটির প্রয়োজন ছিল needed


হাইডি এসকিউএল এর মতো ভিজ্যুয়াল সরঞ্জামগুলিতে এটি একমাত্র কাজের উপায় বলে মনে হচ্ছে।
Altair7852

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';
জেসেন

সেটটি এসকিউএল নয় এটি একটি পিএসকিএল অন্তর্নির্মিত কমান্ড এসকিউএল মন্তব্যগুলি সমর্থন করে না।
জেসেন

2

আমি সত্যিই এই বৈশিষ্ট্য মিস করছি। অনুরূপ কিছু অর্জনের একমাত্র উপায় হ'ল ফাংশন ব্যবহার করা।

আমি এটি দুটি উপায়ে ব্যবহার করেছি:

  • পার্ল ফাংশন যা $ _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';

মন্তব্য:

  • plperlu পার্ল চেয়ে দ্রুত
  • পিজি_ব্যাকেন্ড_পিড সেরা সেশন সনাক্তকরণ নয়, পিজি_স্ট্যাট_অ্যাক্টিভিটি থেকে ব্যাকএন্ড_স্টার্টের সাথে মিলিত পিড ব্যবহার বিবেচনা করুন
  • এই টেবিল সংস্করণটিও খারাপ কারণ আপনাকে মাঝে মাঝে এটি পরিষ্কার করতে হবে (এবং বর্তমানে চলমান সেশন ভেরিয়েবলগুলি মুছবেন না)

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
সেমিকোলনটি আপনার জন্য অপ্রত্যাশিত জিনিসগুলি করার কারণটি হ'ল একটি সেমিকোলন একটি এসকিউএল স্টেটমেন্টটি সমাপ্ত করে, তবে আপনি একটি পিএসকিএল কমান্ড লিখছেন, সেট, যা এসকিউএল নয় এবং একটি সমাধিক সেমিকোলন নেয় না। পরবর্তী লাইনে একটি সেমিকোলন রাখলে ক্ষতি হবে না, তবে একেবারেই কিছুই করবে না। এটি একটি খালি বিবৃতি।
ভোলার্ক

1

আমি অন্য থ্রেডে এর জন্য একটি নতুন সমাধান পোস্ট করেছি ।

এটি ভেরিয়েবলগুলি সংরক্ষণ করতে একটি টেবিল ব্যবহার করে এবং যে কোনও সময় আপডেট করা যায়। একটি স্ট্যাটিক অপরিবর্তনীয় গিটার ফাংশনটি গতিশীলভাবে তৈরি হয় (অন্য ফাংশন দ্বারা), আপনার টেবিলের আপডেট দ্বারা ট্রিগার করা। আপনি সুন্দর টেবিল স্টোরেজ পান, প্লাস জ্বলনকারী দ্রুত গতিতে অপরিবর্তনীয় গেটর।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.