Sorgu sonucunu PL / pgSQL kullanarak bir değişkende saklayın


130

PostgreSQL'in prosedür dili olan PL / pgSQL'deki bir değişkene bir sorgunun sonucu nasıl atanır?

Bir işlevim var:

CREATE OR REPLACE FUNCTION test(x numeric)
RETURNS character varying AS
$BODY$
DECLARE
name   character varying(255);
begin
 name ='SELECT name FROM test_table where id='||x;

 if(name='test')then
  --do somthing
 else
  --do the else part
 end if;
end;
return -- return my process result here
$BODY$
LANGUAGE plpgsql VOLATILE

Yukarıdaki işlevde bu sorgunun sonucunu kaydetmem gerekiyor:

'SELECT name FROM test_table where id='||x;

değişkene name .

Bu nasıl işlenir?

Yanıtlar:


198

Sanırım arıyorsun SELECT INTO:

select test_table.name into name from test_table where id = x;

Yani çeker namegelen test_tablenerede idsenin işlevin argümanı ve bırakın namedeğişken. Tablo adı önekini atlamayın, test_table.nameaksi takdirde belirsiz bir referans hakkında şikayetler alırsınız.


2
Ya birden çok değişkene ihtiyacım olursa. Select test_table.name, test_table.id, test_table.ssn gibi mi?
Dao Lam 15

2
@ DaoLam: Dokümantasyondan şunu beğendim: "Tek bir satır (muhtemelen birden çok sütundan oluşan) veren bir SQL komutunun sonucu bir kayıt değişkenine, satır tipi değişkene veya skaler değişkenler listesine atanabilir."
mu çok kısa

@muistooshort yani aynı şeyi yapabileceğimi ve almak için name.id, name.ssn kullanabileceğimi söylüyorsun? IF EXISTS ile denedim ama işe yaramadı: EĞER VARSA (test_tablosundan isme * seçin ...))
Dao Lam 15

@DaoLam Neden INTO'yu IF EXISTS ile birleştiriyorsunuz? Belki de ne yapmaya çalıştığınızı açıklayabilmek için yeni bir soru sormalısınız.
mu çok kısa

3
Dokümantasyonda örnek yok (ya da kaçırdım), ancak @muistooshort'un da belirttiği gibi, tek bir SELECT test_table.column1, test_table.column2 INTO variable1, variable2 FROM test_table WHERE id = x;
seçimle

78

Tek bir değişken atadığınız sürece, bir plpgsql fonksiyonunda düz atama da kullanabilirsiniz:

name := (SELECT t.name from test_table t where t.id = x);

Veya zaten sağlanan @muSELECT INTO gibi kullanın .

Bu da işe yarar:

name := t.name from test_table t where t.id = x;

Ancak @Pavel'in de belirttiği gibi, ilk iki, daha net yöntemlerden birini kullansanız iyi olur.

Sözdizimini ek olarak bir tablo takma adıyla kısalttım.
Güncelleme: Kod örneğimi kaldırdım ve IF EXISTS()bunun yerine @Pavel tarafından sağlanan gibi kullanmayı önerdim .


1
Bu iyi bir fikir değil - bu özellik belgelenmemiş ve çirkin
Pavel Stehule

2
PL / pgSQL, SQL ve PL'nin karışımına izin verir - ve bazen gerçekten garip yaratıklar yaratabilirsiniz, ancak PL ve SQL'i ayrı ifadelerde temiz bir şekilde karıştırmak daha iyidir.
Pavel Stehule

@PavelStehule: Kabul ediyorum, formunuz tercih edilebilir.
Erwin Brandstetter

Aslında sözdiziminizi tercih ediyorum, ancak sorun şu ki, hataları işlemek istediğinizde, ifadeniz BULUNAN ifadenin tersine doğru ifadeyi göndermiyor, checkout ( postgresql.org/docs/9.1/plpgsql-statements.html )
SENHAJI RHAZI Hamza

18

Genel model şudur EXISTS(subselect):

BEGIN
  IF EXISTS(SELECT name
              FROM test_table t
             WHERE t.id = x
               AND t.name = 'test')
  THEN
     ---
  ELSE
     ---
  END IF;

Bu kalıp PL / SQL, PL / pgSQL, SQL / PSM, ...


2

Öğrenim Tablosu Oluşturun:

CREATE TABLE "public"."learning" (
    "api_id" int4 DEFAULT nextval('share_api_api_id_seq'::regclass) NOT NULL,
    "title" varchar(255) COLLATE "default"
);

Veri Öğrenme Tablosu Ekle:

INSERT INTO "public"."learning" VALUES ('1', 'Google AI-01');
INSERT INTO "public"."learning" VALUES ('2', 'Google AI-02');
INSERT INTO "public"."learning" VALUES ('3', 'Google AI-01');

Adım: 01

CREATE OR REPLACE FUNCTION get_all (pattern VARCHAR) RETURNS TABLE (
        learn_id INT,
        learn_title VARCHAR
) AS $$
BEGIN
    RETURN QUERY SELECT
        api_id,
        title
    FROM
        learning
    WHERE
        title = pattern ;
END ; $$ LANGUAGE 'plpgsql';

Adım: 02

SELECT * FROM get_all('Google AI-01');

Adım: 03

DROP FUNCTION get_all();

Demo: görüntü açıklamasını buraya girin


-2

PL / pgSQL kullanarak bir değişkende bir sorgu sonucunu depolamak için aşağıdaki örneği kullanabilirsiniz:

 select * into demo from maintenanceactivitytrack ; 
    raise notice'p_maintenanceid:%',demo;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.