将查询结果存储在 PL/pgSQL 变量中

问题描述 投票:0回答:8

如何将查询结果赋给PL/pgSQL中的变量?

我有一个功能:

CREATE OR REPLACE FUNCTION test(x numeric)
  RETURNS character varying
  LANGUAGE plpgsql AS
$BODY$
DECLARE
   name character varying(255);
BEGIN
   name = 'SELECT name FROM test_table where id = ' || x;
  
   if name = 'test' then
      -- do something
   else
      -- do something else
   end if;

   return ...  -- return my process result here
END
$BODY$;

在上面的函数中,我需要将此查询的结果存储到变量

name

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

如何处理?

sql postgresql function plpgsql
8个回答
300
投票

我认为您正在寻找

SELECT select_expressions INTO

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

这将从

name
中提取
test_table
,其中
id
是函数的参数,并将其保留在
name
变量中。不要遗漏
test_table.name
上的表名前缀,否则您会收到关于引用不明确的投诉。


152
投票

要分配单个变量,您还可以在 PL/pgSQL 代码块中使用简单赋值,并在右侧使用标量子查询

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

实际上与

SELECT INTO
相同,如@mu已经提供了,但有细微的差别:

  • SELECT INTO
    在我对 Postgres 14 的测试中稍微快一些。
    (不涉及
    SELECT
    的简单常量赋值仍然快了 10 倍。)
  • SELECT INTO
    还设置 特殊变量
    FOUND
    ,而普通赋值则不会。您可能想要其中之一。
  • SELECT INTO
    还可以一次分配多个变量。看:

值得注意的是,这也有效:

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

无前导

SELECT
SELECT
语句。但我不会使用这种混合动力。最好使用前两种更清晰、有记录的方法之一,正如@Pavel 评论的那样。


23
投票
EXISTS(subselect)


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

此模式用于 PL/SQL、PL/pgSQL、SQL/PSM...


4
投票
person

表,然后如下所示向其中插入2行:

CREATE TABLE person (
  id INT,
  name VARCHAR(20)
);

INSERT INTO person (id, name) VALUES (1, 'John'), (2, 'David');

然后,你可以创建
my_func()

,它可以将查询结果存储到

person_name
中,然后返回它,如下所示:
CREATE FUNCTION my_func()
RETURNS VARCHAR(20)
AS $$
DECLARE
  person_id public.person.id%TYPE := 2;
  person_name public.person.name%TYPE;
BEGIN
  SELECT name INTO person_name FROM person WHERE id = person_id;
  RETURN person_name;
END;
$$ LANGUAGE plpgsql;

然后,调用
my_func()

返回

David
,如下所示:
postgres=# SELECT my_func();
 my_func
---------
 David
(1 row)

并且,您可以创建
my_func()

,它可以将查询结果存储到

person_row
中,然后返回它,如下所示:
CREATE FUNCTION my_func()
RETURNS person
AS $$
DECLARE
  person_row public.person%ROWTYPE; -- Here
  -- person_row RECORD; -- Here
BEGIN
  SELECT * INTO person_row FROM person WHERE id = 2;
  RETURN person_row;
END;
$$ LANGUAGE plpgsql;

然后,调用 
my_func()

返回一行,如下所示:

postgres=# SELECT my_func();
  my_func
-----------
 (2,David)
(1 row)



3
投票
创建学习表:

CREATE TABLE "public"."learning" ( "api_id" int4 DEFAULT nextval('share_api_api_id_seq'::regclass) NOT NULL, "title" varchar(255) COLLATE "default" );
  
插入数据学习表:

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');
  
步骤: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';
  
步骤:02

SELECT * FROM get_all('Google AI-01');
  
步骤:03

DROP FUNCTION get_all();
演示:

enter image description here


3
投票
执行具有单行结果的查询

,请使用以下语法: SELECT select_expressions INTO [STRICT] target FROM ...

其中 
target

可以是记录变量、行变量或以逗号分隔的简单变量和记录/行字段列表。

SELECT INTO

不同,

SELECT select_expressions INTO
不会创建表格。
在您的示例中,您有一个简单变量

name

,因此 select 语句将是:

SELECT test_table.name INTO name FROM test_table WHERE test_table.id = x;



1
投票

这里是使用postgres中函数的示例(包括声明、变量、参数、返回值和运行)。下面是一种用“hello world”更新右下角“blurb”推文的过度烘焙方法。

id(序列号)12
pub_id(文本) 推文(文字)
abc 世界你好
定义 宣传
-- Optional drop if replace fails below. drop function if exists sync_tweets(text, text); create or replace function sync_tweets( src_pub_id text, -- function arguments dst_pub_id text ) returns setof tweets as -- i.e. rows. int, text work too $$ declare src_id int; -- temp function variables (not args) dest_id int; src_tweet text; begin -- query result into a temp variable src_id := (select id from tweets where pub_id = src_pub_id); -- query result into a temp variable (another way) select tweet into src_tweet from tweets where id = src_id; dest_id := (select id from tweets where pub_id = dst_pub_id); update tweets set tweet=src_tweet where id = dest_id; return query -- i.e. rows, return 0 with return int above works too select * from tweets where pub_id in (src_pub_id, dst_pub_id); end $$ language plpgsql; -- need the language to avoid ERROR 42P13 -- Run it! select * from sync_tweets('abc', 'def'); /* Outputs __________________________________________________ | id (serial) | pub_id (text) | tweet (text) | |---------------|-----------------|----------------| | 1 | abc | hello world | | 2 | def | blurb | -------------------------------------------------- */


-3
投票

select * into demo from maintenanceactivitytrack ; raise notice'p_maintenanceid:%',demo;

	
© www.soinside.com 2019 - 2024. All rights reserved.