Postgres:如何从函数中分配自定义类型?

时间:2013-12-07 21:27:11

标签: function postgresql parameter-passing plpgsql custom-type

我想在函数中检索自定义类型,并将其用作另一个函数的参数来复制记录。在下面的代码中,我展示了检索自定义类型并将其用作函数的参数都成功:分别参见getWholeWeatherData()和addWholeWeatherData()。

有关问题,请参阅dupwd()。如何将getWholeWeatherData()中自定义类型的输出作为参数传递给addWholeWeatherData(),两者都可以自行成功。

$ 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;

以下是运行脚本的输出:

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)

1 个答案:

答案 0 :(得分:1)

在plpgsql函数中,当调用函数并想要丢弃返回值时,必须使用PERFORM代替SELECT

所以,在你的函数dupwd()中:

SELECT addWholeWeatherData(dr);
PERFORM addWholeWeatherData(dr);

当然,您可以简化通话。对于所呈现的简单情况,您不需要中间变量。你甚至不需要一个单独的功能。只是:

SELECT addWholeWeatherData(getWholeWeatherData(observ_id));