如何将查询结果赋给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;
如何处理?
SELECT select_expressions INTO
:
select test_table.name into name from test_table where id = x;
这将从
name
中提取 test_table
,其中 id
是函数的参数,并将其保留在 name
变量中。不要遗漏 test_table.name
上的表名前缀,否则您会收到关于引用不明确的投诉。
要分配单个变量,您还可以在 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 评论的那样。
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...
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)
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();
这里是使用postgres中函数的示例(包括声明、变量、参数、返回值和运行)。下面是一种用“hello world”更新右下角“blurb”推文的过度烘焙方法。
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 |
--------------------------------------------------
*/
select * into demo from maintenanceactivitytrack ;
raise notice'p_maintenanceid:%',demo;