I want to retrieve a custom type in a function and use it as a parameter to another function to duplicate the record. In the code below I show that both retrieving a custom type and using it as a parameter to a function succeeds: see getWholeWeatherData() and addWholeWeatherData() respectively.
For the question, see dupwd(). How do I pass the output of custom type from getWholeWeatherData() as a parameter to addWholeWeatherData(), both of which succeed on their own.
$ psql --version psql (PostgreSQL) 9.3.0
DROP TABLE IF EXISTS wd;
DROP TYPE IF EXISTS wtype CASCADE;
CREATE TYPE wtype AS (
latitude NUMERIC,
longitude NUMERIC,
temp NUMERIC,
barometer NUMERIC
);
DROP FUNCTION IF EXISTS getWholeWeatherData(INTEGER);
DROP FUNCTION IF EXISTS addWholeWeatherData(wtype);
DROP FUNCTION IF EXISTS dupwd(INTEGER);
DROP FUNCTION IF EXISTS tryAddWholeWeatherData();
CREATE TABLE wd
(
wo_id SERIAL PRIMARY KEY,
datetime TIMESTAMP NOT NULL,
latitude NUMERIC(9, 6) NOT NULL,
longitude NUMERIC(9, 6) NOT NULL,
temp NUMERIC(4, 1),
barometer NUMERIC(4, 2),
comment TEXT
);
CREATE OR REPLACE FUNCTION getWholeWeatherData(observ_id INTEGER)
RETURNS wtype AS $$
DECLARE
returnrec wtype%ROWTYPE;
BEGIN
SELECT INTO returnrec
latitude,
longitude,
temp,
barometer
FROM wd WHERE wo_id = observ_id;
RETURN returnrec;
END;
$$ LANGUAGE plpgsql;
-- This works
CREATE OR REPLACE FUNCTION addWholeWeatherData(weather wtype)
RETURNS INTEGER AS $$
DECLARE
observ_id INTEGER;
BEGIN
INSERT INTO wd (
datetime,
latitude,
longitude,
temp,
barometer,
comment
)
VALUES (
localtimestamp,
weather.latitude,
weather.longitude,
weather.temp,
weather.barometer,
'just a test'
)
RETURNING wo_id INTO observ_id;
RETURN observ_id;
END;
$$ LANGUAGE plpgsql;
-- This works
CREATE OR REPLACE FUNCTION tryAddWholeWeatherData()
RETURNS INTEGER AS $$
DECLARE
wdd wtype;
woid INTEGER;
BEGIN
wdd.longitude = 99.99999;
wdd.latitude = 88.88888;
wdd.temp = 77.77;
wdd.barometer = 66.666;
SELECT INTO woid addWholeWeatherData(wdd);
RETURN woid;
END;
$$ LANGUAGE plpgsql;
-- This is the question
CREATE OR REPLACE FUNCTION dupwd(observ_id INTEGER)
RETURNS VOID AS $$
DECLARE
dr wtype;
BEGIN
-- ??? How to get wtype result from getWholeWeatherData() into variable dr wtype
SELECT INTO dr getWholeWeatherData(observ_id);
-- ??? This should work if I could get the value for dr from getWholeWeatherData()
SELECT addWholeWeatherData(dr);
END;
$$ LANGUAGE plpgsql;
-- Get started with a record
INSERT INTO wd (
datetime,
latitude,
longitude,
temp,
barometer,
comment
)
VALUES (
localtimestamp,
12.3456,
23.4567,
123,
29.345,
'initial data'
);
SELECT * FROM wd;
-- Successfully retrieves a wtype record
SELECT getWholeWeatherData(1);
-- Successfully adds a wtype record
--SELECT tryAddWholeWeatherData();
-- duplicate a record
SELECT dupwd(1);
SELECT * FROM wd;
Here is the output of running the script:
INSERT 0 1
wo_id | datetime | latitude | longitude | temp | barometer | comment
-------+----------------------------+-----------+-----------+-------+-----------+--------------
1 | 2013-12-07 13:18:14.127465 | 12.345600 | 23.456700 | 123.0 | 29.35 | initial data
(1 row)
getwholeweatherdata
-----------------------------------
(12.345600,23.456700,123.0,29.35)
(1 row)
tryaddwholeweatherdata
------------------------
2
(1 row)
wo_id | datetime | latitude | longitude | temp | barometer | comment
-------+----------------------------+-----------+-----------+-------+-----------+--------------
1 | 2013-12-07 13:18:14.127465 | 12.345600 | 23.456700 | 123.0 | 29.35 | initial data
2 | 2013-12-07 13:18:14.129907 | 88.888880 | 99.999990 | 77.8 | 66.67 | just a test
(2 rows)
psql:q1.sql:126: ERROR: invalid input syntax for type numeric: "(12.345600,23.456700,123.0,29.35)"
CONTEXT: PL/pgSQL function dupwd(integer) line 6 at SQL statement
wo_id | datetime | latitude | longitude | temp | barometer | comment
-------+----------------------------+-----------+-----------+-------+-----------+--------------
1 | 2013-12-07 13:18:14.127465 | 12.345600 | 23.456700 | 123.0 | 29.35 | initial data
2 | 2013-12-07 13:18:14.129907 | 88.888880 | 99.999990 | 77.8 | 66.67 | just a test
(2 rows)
In a plpgsql function you have to use
PERFORM
in place ofSELECT
when you call a function and want to discard the return value.So, in your function
dupwd()
:Of course, you can simplify the call. You don't need an intermediate variable for the presented simple case. You don't even need a separate function. Just: