পোস্টগ্রিএসকিউএল কোয়েরিতে কীভাবে কোনও ভেরিয়েবল ঘোষণা করবেন


241

পোস্টগ্রিসএসকিউএল 8.3 কোয়েরিতে আমি কীভাবে ভেরিয়েবলের ঘোষণা করব?

এমএস এসকিউএল সার্ভারে আমি এটি করতে পারি:

DECLARE @myvar INT
SET @myvar = 5

SELECT *
FROM somewhere
WHERE something = @myvar

পোস্টগ্র্রেএসকিউএল এ আমি কীভাবে করব? ডকুমেন্টেশন অনুসারে ভেরিয়েবলগুলি কেবল "নাম টাইপ;" হিসাবে ঘোষণা করা হয়, তবে এটি আমাকে একটি সিনট্যাক্স ত্রুটি দেয়:

myvar INTEGER;

কেউ আমাকে সঠিক সিনট্যাক্সের উদাহরণ দিতে পারে?


2
এটি কেবল পোস্টগ্র্যাসকিউএল এ করা যেতে পারে। এই সম্পর্কিত প্রশ্নের উত্তর দেখুন: স্ট্যাকওভারফ্লো.com
শন দ্য

2
এই সম্পর্কিত উত্তরের আরও উত্তম উত্তর রয়েছে: stackoverflow.com/questions/13316773/…
এরউইন ব্র্যান্ডসটেটার

উত্তর:


113

PostgreSQL এ তেমন কোনও বৈশিষ্ট্য নেই। আপনি এটি কেবলমাত্র pl / PgSQL (বা অন্যান্য pl / *) এ করতে পারেন, তবে সরল এসকিউএলে নয়।

একটি ব্যতিক্রম WITH ()ক্যোয়ারী যা ভেরিয়েবল বা এমনকি ভেরিয়েবল হিসাবে কাজ করতে পারে tuple। এটি আপনাকে অস্থায়ী মানগুলির একটি সারণী ফেরত দিতে দেয়।

WITH master_user AS (
    SELECT
      login,
      registration_date
    FROM users
    WHERE ...
)

SELECT *
FROM users
WHERE master_login = (SELECT login
                      FROM master_user)
      AND (SELECT registration_date
           FROM master_user) > ...;

আমি ভেটেবল হিসাবে ব্যবহৃত হচ্ছে সিটিই এর এই পদ্ধতিটি চেষ্টা করেছিলাম। তবে আমি দ্রুত কোনও সমস্যার মধ্যে ছুঁড়েছি যেখানে সিটিইতে বিভিন্ন ডেটা পরিবর্তনকারী কোয়েরি একে অপরের প্রভাব দেখার গ্যারান্টিযুক্ত নয়। একাধিক ক্যোয়ারিতে সেই পরিবর্তনশীলটি ব্যবহার করার জন্য আমার প্রয়োজন হিসাবে একাধিক সিটিই ব্যবহার করতে হয়েছিল।
জিয়া উল রেহমান মুঘল

227

আমি একটি WITHধারা ব্যবহার করে একই লক্ষ্য অর্জন করেছি , এটি মার্জিত হিসাবে আর কাছাকাছি কিন্তু একই জিনিস করতে পারে do যদিও এই উদাহরণের জন্য এটি সত্যিই অতিমাত্রার। আমিও বিশেষভাবে এটি সুপারিশ করি না।

WITH myconstants (var1, var2) as (
   values (5, 'foo')
)
SELECT *
FROM somewhere, myconstants
WHERE something = var1
   OR something_else = var2;

2
এটি বেশিরভাগ দৃষ্টান্তের জন্য দুর্দান্ত কাজ করে যেখানে আপনি ভেরিয়েবলগুলি চান। তবে, আপনি যদি LIMIT- এর (যা ভেরিয়েবলগুলি ধারণ করতে পারে না) জন্য কোনও ভেরিয়েবল ব্যবহার করতে চান, তবে আপনি \setশাহরিয়ার অহজানীর উত্তরে প্রস্তাবিত হিসাবে ব্যবহার করতে চান ।
cimmanon

1
এটি যখন আমার কাছে মাইগ্রেশন স্ক্রিপ্ট থাকে তখন আমি কিছু সম্পর্কিত ডেটা আমদানি করতে চাই ideal স্পষ্টতই আমি জানব না যে সম্পর্কিত তথ্যটি দেওয়া হয়েছে সিকোয়েন্স আইডি।
পুনঃপ্রকাশ

3
আমি কেবল এই পদ্ধতির চেষ্টা করেছি এবং সম্ভবত আরও ভাল উপায় খুঁজে পেয়েছি: JOIN myconstants ON trueএবং তারপরে সাব-সিলেক্ট করার দরকার নেই।
ভেকটর

7
এটি কেবল একটি একক ক্যোয়ারির মধ্যেই কাজ করে, আপনি WITHকোনও লেনদেনের মধ্যে কোয়েরিতে সিটিই ভাগ করতে পারবেন না ।
দেনিথ

2
প্রাচীন প্রশ্ন হচ্ছে, কিন্তু এখানে এখানে একটি প্রকরণ রয়েছে: WITH constants AS (SELECT 5 AS var) SELECT * FROM somewhere CROSS JOIN constants WHERE someting=var;। ক্রস যোগদান, একটি একক সারি টেবিল এক্সপ্রেশন সহ একটি, প্রকৃত টেবিলের সমস্ত সারি জন্য কার্যত ডুপ্লিকেট, এবং অভিব্যক্তি সরলকরণ।
মানংগো

82

আপনি PLPGSQL এ এটি ব্যবহার করে দেখতে পারেন:

DO $$
DECLARE myvar integer;
BEGIN
    SELECT 5 INTO myvar;

    DROP TABLE IF EXISTS tmp_table;
    CREATE TABLE tmp_table AS
    SELECT * FROM yourtable WHERE   id = myvar;
END $$;

SELECT * FROM tmp_table;

উপরোক্ত পোস্টগ্রিস 9.0 বা তার পরে প্রয়োজন।


1
ডিও স্টেটমেন্টটি পোস্টগ্রিসকিউএল 9.0 এ যুক্ত হয়েছিল এবং 8.3-এ কাজ করে না।
জনি

14
টেবিল তৈরি করুন না, তৈরি টেবিল তৈরি করুন বা টেবিল তৈরি করুন। তবে অন্যথায় জরিমানা।
স্টিফান স্টেইগার

60

ডায়নামিক কনফিগারেশন সেটিংস

আপনি এর জন্য ডায়নামিক কনফিগারেশন সেটিংস "অপব্যবহার" করতে পারেন:

-- choose some prefix that is unlikely to be used by postgres
set session my.vars.id = '1';

select *
from person 
where id = current_setting('my.vars.id')::int;

কনফিগারেশন সেটিংস সর্বদা ভারচর মান হয়, তাই এগুলি ব্যবহার করার সময় আপনার এগুলি সঠিক ডেটা টাইপে কাস্ট করতে হবে। এটি যে কোনও এসকিউএল ক্লায়েন্টের সাথে কাজ করে যেখানে \setকেবলমাত্র কাজ করেpsql

উপরের পোস্টগ্রিস 9.2 বা তার পরে প্রয়োজন requires

পূর্ববর্তী সংস্করণগুলির জন্য, পরিবর্তনশীলটি postgresql.confব্যবহারের আগে ঘোষিত করতে হয়েছিল , সুতরাং এটি এর ব্যবহার্যতা কিছুটা সীমিত করেছিল। আসলে সম্পূর্ণরূপে চলক নয়, তবে কনফিগারেশন "শ্রেণি" যা মূলত উপসর্গ। তবে একবার উপসর্গটি সংজ্ঞায়িত হয়ে গেলে, কোনও পরিবর্তনশীল পরিবর্তন না করেই ব্যবহার করা যেতে পারেpostgresql.conf


3
@ ব্রিজান এলওয়াদী: হ্যাঁ এটি লেনদেনের।
a_horse_with_no_name

2
একটি সাইড নোট হিসাবে: কিছু শব্দ উদাহরণস্বরূপ সংরক্ষিত পরিবর্তন set session my.vars.id = '1';করতে set session my.user.id = '1';সমর্পণ করা হবেERROR: syntax error at or near "user"
ডমিনিক

2
@BrijanElwadhi: করতে পরিবর্তনশীল লেনদেন নির্দিষ্ট আপনি ব্যবহার করতে হবে: SET LOCAL ...sessionপরিবর্তনশীল যতদিন না পর্যন্ত আপনি সংযোগ যেমন প্রভাব থাকবে। localলেনদেনের জন্য scoped হয়।
ইউজেন কনকভ

@ ডোমিনিক আপনি এই সীমাবদ্ধতাটি উদ্ধৃতি সহ পেতে পারেন, যেমন set session "my.user.id" = '1';The current_setting('my.user.id')কলটি প্রত্যাশা অনুযায়ী কাজ করে।
মাইলস এলেম

58

এটি আপনার ক্লায়েন্টের উপর নির্ভর করে।

তবে আপনি যদি পিএসএইচএল ক্লায়েন্ট ব্যবহার করেন তবে আপনি নিম্নলিখিতটি ব্যবহার করতে পারেন:

my_db=> \set myvar 5
my_db=> SELECT :myvar  + 1 AS my_var_plus_1;
 my_var_plus_1 
---------------
             6

আপনি যদি পাঠ্য ভেরিয়েবল ব্যবহার করছেন তবে আপনার উদ্ধৃতি দিতে হবে।

\set myvar 'sometextvalue'
select * from sometable where name = :'myvar';

1
\setছোট হাতের অক্ষরে করা আবশ্যক
deluan

db = # \ প্রোফাইল_আইডি 102 সেট করুন db = #: প্রোফাইল_আইডি; ত্রুটি: "102" লাইন 1: 102 বা এর কাছাকাছি সিনট্যাক্স ত্রুটি; ^
অ্যালেক্সভাল্লেজো

1
@ অ্যালেক্সওয়াল্লেজো আপনাকে এটিকে স্টেটমেন্ট এবং পিএসএইচএল কনসোলে ব্যবহার করতে হবে । db=> \set someid 8292 db=> SELECT * FROM sometable WHERE id = :someid;
সর্বদা

21

Pl / PgSQL এর বাইরে একটি টেম্প টেবিল ব্যবহার করা

প্রস্তাবিত হিসাবে pl / pgsql বা অন্যান্য pl / * ভাষা ব্যবহারের বাইরে, এটিই আমি ভাবতে পারি other

begin;
select 5::int as var into temp table myvar;
select *
  from somewhere s, myvar v
 where s.something = v.var;
commit;

13

অস্থায়ী সারণীগুলি সহজতর করার পক্ষে, আমি @ ডারিওবায়ারিয়ানোভোর উত্তরের উন্নতির প্রস্তাব দিতে চাই ।

DO $$
    DECLARE myvar integer = 5;
BEGIN
    CREATE TEMP TABLE tmp_table ON COMMIT DROP AS
        -- put here your query with variables:
        SELECT * 
        FROM yourtable
        WHERE id = myvar;
END $$;

SELECT * FROM tmp_table;

ডিও ব্লক সমাধানের জন্য দুর্দান্ত সমাধান ডেটা সেট ফেরত দিতে পারে না!
কোডফার্মার

পোস্টগ্র্যাসকিউএল ১১.০-তে, এই জাতীয় একটি কোয়েরিটির 1বিষয়বস্তুগুলির পরিবর্তে (সম্ভবতঃ সারি গণনা) প্রদান করে tmp_table
এড নোপেল

9

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

মূলত, প্রতিটি ধ্রুবক হ'ল একটি একক মানের মূল্য সারণী যা একটি উইথ ক্লজে ঘোষিত হয় যা কোয়েরির অবশিষ্ট অংশে যে কোনও জায়গায় বলা যেতে পারে।

  • দুটি ধ্রুবক সহ বেসিক উদাহরণ:
WITH
    constant_1_str AS (VALUES ('Hello World')),
    constant_2_int AS (VALUES (100))
SELECT *
FROM some_table
WHERE table_column = (table constant_1_str)
LIMIT (table constant_2_int)

বিকল্পভাবে আপনি এর SELECT * FROM constant_nameপরিবর্তে ব্যবহার করতে পারেন TABLE constant_nameযা পোস্টগ্রেএসকিএল থেকে আলাদা অন্যান্য কোয়েরি ভাষার জন্য বৈধ নয়।


6

এখানে PREPARE স্টেটমেন্ট ব্যবহার করে একটি উদাহরণ দেওয়া হল । আপনি এখনও ব্যবহার করতে পারবেন না ?, তবে আপনি $nস্বরলিপিটি ব্যবহার করতে পারেন :

PREPARE foo(integer) AS
    SELECT  *
    FROM    somewhere
    WHERE   something = $1;
EXECUTE foo(5);
DEALLOCATE foo;

বেশ ভাল কাজ করে! ধন্যবাদ।
রুই কারওয়ালহো

4

সত্য, কোনও একক মান ভেরিয়েবল ঘোষণার জন্য কোনও স্পষ্ট এবং দ্ব্যর্থহীন উপায় নেই, আপনি যা করতে পারেন তা

with myVar as (select "any value really")

তারপরে, এই নির্মাণে সঞ্চিত মানটিতে অ্যাক্সেস পেতে, আপনি তা করেন

(select * from myVar)

উদাহরণ স্বরূপ

with var as (select 123)    
... where id = (select * from var)

3

আপনি সরঞ্জাম বিশেষ বৈশিষ্ট্য অবলম্বন করতে পারেন। ডিবিভারের নিজস্ব মালিকানাধীন সিনট্যাক্সের জন্য পছন্দ করুন:

@set name = 'me'
SELECT :name;
SELECT ${name};

DELETE FROM book b
WHERE b.author_id IN (SELECT a.id FROM author AS a WHERE a.name = :name);

এটি ব্যবহারযোগ্যতার কাছাকাছি: আমি ডিবিভার তালিকাগুলি এবং লুপিং সমর্থন করে কিনা তা আমি খতিয়ে দেখতে যাচ্ছি: আমার একাধিক স্কিমায় একই স্কেলটি প্রয়োগ করা প্রয়োজন এবং সেগুলি প্রয়োগ করার জন্য তালিকাটি স্কিমার মধ্যে থাকবে।
জাভাদবা

1

ডিবিভারে আপনি কোয়েরিতে প্যারামিটারগুলি কোড থেকে যেমন ব্যবহার করতে পারেন তেমন ব্যবহার করতে পারেন, সুতরাং এটি কাজ করবে:

SELECT *
FROM somewhere
WHERE something = :myvar

আপনি যখন ক্যোয়ারি চালাবেন তখন ডিবিভার আপনাকে: মাইভারের জন্য মান জিজ্ঞাসা করবে এবং কোয়েরিটি চালাবে।

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