【问题标题】:Postgres: How to assign to custom type from function?Postgres:如何从函数分配给自定义类型?
【发布时间】:2013-12-07 21:27:10
【问题描述】:

我想在函数中检索自定义类型并将其用作另一个函数的参数以复制记录。在下面的代码中,我展示了检索自定义类型并将其用作函数的参数都成功:分别参见 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)

【问题讨论】:

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


    【解决方案1】:

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

    所以,在你的函数dupwd()

    <strike>SELECT addWholeWeatherData(dr);</strike>
    PERFORM addWholeWeatherData(dr);

    当然,您可以简化调用。对于呈现的简单案例,您不需要中间变量。您甚至不需要单独的功能。只是:

    SELECT addWholeWeatherData(getWholeWeatherData(observ_id));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-03
      • 2012-08-14
      • 2017-10-01
      • 1970-01-01
      • 2021-04-16
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      相关资源
      最近更新 更多