http://www.postgresonline.com/journal/archives/201-Using-RETURNS-TABLE-vs.-OUT-parameters.html
http://www.postgresql.org/docs/9.4/interactive/index.html
--http://www.postgresonline.com/journal/archives/201-Using-RETURNS-TABLE-vs.-OUT-parameters.html
--ver:9.3 Geovin Du 涂聚文
--returning a single record using SQL function
CREATE OR REPLACE FUNCTION fn_sqltestout(param_subject text, pos integer)
RETURNS TABLE(subject_scramble text, subject_char text)
AS
$$
SELECT substring($1, 1,CAST(random()*length($1) As integer)) ,
substring($1, 1,1) As subject_char;
$$
LANGUAGE 'sql' VOLATILE;
-- example use
SELECT (fn_sqltestout('This is a test subject',1)).subject_scramble;
SELECT subject_scramble, subject_char FROM fn_sqltestout('This is a test subject',5);
--Same function but written in plpgsql
--PLPGSQL example -- return one record
CREATE OR REPLACE FUNCTION fn_plpgsqltestout(param_subject varchar)
RETURNS TABLE(subject_scramble varchar, subject_char varchar)
AS
$$
BEGIN
subject_scramble := substring($1, 1,CAST(random()*length($1) As varchar));
subject_char := substring($1, 1,1);
RETURN NEXT;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;
-- example use
SELECT (fn_plpgsqltestout('This is a test subject')).subject_scramble;
SELECT subject_scramble, subject_char FROM fn_plpgsqltestout('This is a test subject');
-- test data to use --
CREATE TABLE testtable(id integer PRIMARY KEY, test text);
INSERT INTO testtable(id,test)
VALUES (1, 'Potato'), (2, 'Potato'), (3, 'Cheese'), (4, 'Cheese Dog');
--SQL function returning multiple records
CREATE OR REPLACE FUNCTION fn_sqltestmulti(param_subject varchar)
RETURNS TABLE(test_id integer, test_stuff text)
AS
$$
SELECT id, test
FROM testtable WHERE test LIKE $1;
$$
LANGUAGE 'sql' VOLATILE;
-- example use
SELECT (fn_sqltestmulti('Cheese%')).test_stuff;
SELECT test_stuff FROM fn_sqltestmulti('Cheese%');
-- plpgsql function returning multiple records
-- note RETURN QUERY was introduced in 8.3
-- variant 1
CREATE OR REPLACE FUNCTION fn_plpgsqltestmulti(param_subject varchar)
RETURNS TABLE(test_id integer, test_stuff text)
AS
$$
BEGIN
RETURN QUERY SELECT id, test
FROM testtable WHERE test LIKE param_subject;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;
--测试
select * from fn_plpgsqltestmulti('Cheese%');
-- variant 2 use this if you need to do something additional
-- or conditionally return values or more dynamic stuff
-- RETURN QUERY is generally more succinct and faster
CREATE OR REPLACE FUNCTION fn_plpgsqltestmulti(param_subject varchar)
RETURNS TABLE(test_id integer, test_stuff text)
AS
$$
DECLARE
var_r record;
BEGIN
FOR var_r IN(SELECT id, test
FROM testtable WHERE test LIKE param_subject) LOOP
test_id := var_r.id ; test_stuff := var_r.test;
RETURN NEXT;
END LOOP;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;
-- example use
-- This is legal in PostgreSQL 8.4+
-- (prior versions plpgsql could not be called this way)
SELECT (fn_plpgsqltestmulti('Cheese%')).test_stuff;
SELECT * FROM fn_plpgsqltestmulti('Cheese%');
--函数 涂聚文 Geovin Du
CREATE FUNCTION check_password(uname TEXT, pass TEXT)
RETURNS BOOLEAN AS $$
DECLARE passed BOOLEAN;
BEGIN
SELECT (pwd = $2) INTO passed
FROM pwds
WHERE username = $1;
RETURN passed;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER
-- Set a secure search_path: trusted schema(s), then 'pg_temp'.
SET search_path = admin, pg_temp;
---http://www.postgresql.org/docs/current/static/sql-createfunction.html
CREATE OR REPLACE function f_GetDepartmentName
(
did integer
)
returns varchar as $$
declare str varchar;
begin
select DepartmentName INTO str from DepartmentList where DepartmentID=did;
return str;
end;
$$language plpgsql;
--测试
select f_GetDepartmentName(1) as name;
--( (select DepartmentName from DepartmentList where DepartmentID = in_id) union (select name from test_result2 where id = in_id) )
CREATE OR REPLACE FUNCTION func_DepartmentMore ( in_id integer)
RETURNS SETOF varchar as
$$
DECLARE
v_name varchar;
BEGIN
for v_name in (select DepartmentName from DepartmentList where DepartmentID = in_id)loop
RETURN NEXT v_name;
end loop;
return;
END;
$$
LANGUAGE PLPGSQL;
---
select func_DepartmentMore(1);
---
CREATE OR REPLACE FUNCTION func_DepartmentName_muti (in_id integer)
RETURNS SETOF RECORD as
$$
DECLARE
v_rec RECORD;
BEGIN
for v_rec in (select DepartmentID,DepartmentName from DepartmentList where DepartmentID = in_id)loop
RETURN NEXT v_rec;
end loop;
return;
END;
$$
LANGUAGE PLPGSQL;
--测试
select * from func_DepartmentName_muti(1) t(DepartmentID integer,DepartmentName varchar);
CREATE OR REPLACE FUNCTION func_DepartmentName_query ( in_id integer)
RETURNS SETOF RECORD as
$$
DECLARE
v_rec RECORD;
BEGIN
return query(select DepartmentID,DepartmentName from DepartmentList where DepartmentID = in_id);
return;
END;
$$
LANGUAGE PLPGSQL;
--测试
select * from func_DepartmentName_query(1) t(DepartmentID integer,DepartmentName varchar);
---http://www.postgresonline.com/journal/archives/129-Use-of-OUT-and-INOUT-Parameters.html
CREATE OR REPLACE FUNCTION func_DepartmentName_out( in_id integer,out o_id integer,out o_name varchar)
RETURNS SETOF RECORD as
$$
DECLARE
v_rec RECORD;
BEGIN
for v_rec in ( select DepartmentID,DepartmentName from DepartmentList where DepartmentID = in_id)loop
o_id := v_rec.DepartmentID;
o_name := v_rec.DepartmentName;
RETURN NEXT ;
end loop;
return;
END;
$$
LANGUAGE PLPGSQL;
--测试
select DepartmentID,DepartmentName from DepartmentList
select * from func_DepartmentName_out(1);
select * from func_DepartmentName_out(2);
---
CREATE OR REPLACE FUNCTION func_table(in_id int) RETURNS TABLE(f1 int, f2 varchar)
AS
$$
begin
SELECT f1=DepartmentID, f2=DepartmentName from DepartmentList where DepartmentID =in_id;
end;
$$
LANGUAGE SQL;
SELECT * FROM dup(42);
CREATE OR REPLACE FUNCTION fn_plpgsqltestout(param_subject text,
OUT subject_scramble text, OUT subject_char text)
AS
$$
BEGIN
subject_scramble := substring($1, 1,CAST(random()*length($1) As integer));
subject_char := substring($1, 1,1);
END;
$$
LANGUAGE 'plpgsql' VOLATILE;
--测试
select fn_plpgsqltestout('geovindu');
CREATE OR REPLACE FUNCTION fn_sqltestmulti(param_subject varchar,
OUT test_id integer,
OUT test_stuff text)
RETURNS SETOF record
AS
$$
SELECT DepartmentID,DepartmentName
FROM DepartmentList where DepartmentName LIKE $1;
$$
LANGUAGE 'sql' VOLATILE;
--测试
SELECT * FROM fn_sqltestmulti('%d%');
--OUT takes precendence which is why we prefix the table columns
CREATE OR REPLACE FUNCTION fn_plpgsqltestmulti(
param_subject varchar,
OUT test_id integer,
OUT test_stuff varchar)
RETURNS SETOF record
AS
$$
BEGIN
RETURN QUERY SELECT t.DepartmentID , t.DepartmentName
FROM DepartmentList As t
WHERE t.DepartmentName LIKE param_subject;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;
SELECT * FROM fn_plpgsqltestmulti('%d%',1, 'd');