Postgres函数创建但不执行

时间:2014-09-13 01:27:33

标签: sql postgresql plpgsql

我一直在努力尝试这项工作。据我所知,我已经按照文档进行了操作,这只是不起作用。

你们中任何有Postgres经验的人都可以推荐修复吗?我会永远感激。

我使用的是版本1。1。1(2014年6月9日,rev:REL-1_18_1)

我的创建代码:

set search_path = PsychoProductions;
create or replace function fcn_insert_person(
        -- person table
        prm_role_id int, 
        prm_first_name text, 
        prm_last_name text, 
        prm_organization text, 
        prm_website text, 
        prm_default_billing_method_id text, 
        prm_active boolean, 
        -- address table
        prm_address_type_id int, 
        prm_address text, 
        prm_city text, 
        prm_state text, 
        prm_zip_code text, 
        -- email table
        prm_email_address text, 
        prm_email_type_id int, 
        -- phone table
        prm_phone_number text, 
        prm_phone_type_id int
)
returns void as
$$
set search_patch = PsychoProductions;

insert into PsychoProductions.person (
        role_id,
        first_name,
        last_name,
        organization,
        website,
        default_billing_method_id,
        active
        )
values (
        prm_role_id,
        prm_first_name,
        prm_last_name,
        prm_organization,
        prm_website,
        prm_default_Billing_Method_ID,
        prm_active
        );

insert into PsychoProductions.address (
        person_id,
        address_type_id,
        address,
        city,
        state,
        zip_code
        )
values (
        ( select currval('person_id_seq') ),
        prm_address_type_id,
        prm_address,
        prm_city,
        prm_state,
        prm_zip_code
        );

insert into email (
        person_id,
        email_address,
        email_type_id
        )
values (
        ( select currval('person_id_seq') ),
        prm_email_address,
        prm_email_type_id
        );

insert into phone (
        person_id,
        phone_number,
        phone_type_id
        )
values (
        ( select currval('person_id_seq') ),
        prm_phone_number,
        prm_phone_type_id
        );

-- end;
$$
language sql;

我的执行/通话代码:

set search_path = PsychoProductions;
select fcn_insert_person(
-- NOTE: DO NOT REMOVE QUOTATION MARKS
        -- person table
        3,                      -- customer
        'firstname', 
        'lastname', 
        'organization', 
        'website', 
        2,                      -- net 30
        True,                   -- active
        -- address table
        1,                      -- unique
        'address', 
        'city', 
        'state', 
        'zip', 
        -- email table
        'email', 
        1,                      -- business email 
        -- phone table
        'phone', 
        1                       -- mobile
  );

错误:

ERROR:  function fcn_insert_person(integer, unknown, unknown, unknown, unknown, integer, boolean, integer, unknown, unknown, unknown, unknown, unknown, integer, unknown, integer) does not exist
LINE 2: select fcn_insert_person(
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

********** Error **********

ERROR: function fcn_insert_person(integer, unknown, unknown, unknown, unknown, integer, boolean, integer, unknown, unknown, unknown, unknown, unknown, integer, unknown, integer) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 45

2 个答案:

答案 0 :(得分:3)

我有类似的情况 - 具有宽参数列表的功能。使用所谓的命名参数,您无需遵守参数顺序。代码更长,但(我希望)更具可读性和更强大。

CREATE TABLE tab(name text, surname text, address text, city text, zip text);

CREATE OR REPLACE FUNCTION public.fx(name text, surname text,
                                     address text, city text, zip text)
RETURNS void
LANGUAGE plpgsql
AS $function$
BEGIN
  INSERT INTO tab(name, surname, address, city, zip)
    VALUES(fx.name, fx.surname, fx.address, fx.city, fx.zip);
  -- ... some other logic
END;
$function$

可以使用命名参数表示法调用此函数:

SELECT fx(name := 'Pavel', surname := 'Stehule',
          address := 'Skalice 12', city := 'Benesov', zip := '12');

注意:当我使用错误的类型时 - Postgres报告消息:

postgres=#   SELECT fx(name := 'Pavel', surname := 'Stehule',
              address := 'Skalice 12', city := 'Benesov', zip := 12);
ERROR:  function fx(name := unknown, surname := unknown, address := unknown, city := unknown, zip := integer) does not exist
LINE 1: SELECT fx(name := 'Pavel', surname := 'Stehule',
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

该消息有效,但不干净。这是功能重载支持的代价。还有其他技巧,如何划分长参数列表,以及如何更舒适地找到这些问题。

Postgres支持自定义类型。你可以使用它:

CREATE TYPE person_type AS (name text, surname text);
CREATE TYPE address_type AS (address text, city text, zip text);

你可以写一个构造函数:

CREATE OR REPLACE FUNCTION public._person_type(name text, surname text)
RETURNS person_type
LANGUAGE plpgsql
AS $function$
DECLARE r person_type;
BEGIN
  r.name = name;
  r.surname = surname;
  RETURN r;
END;
$function$

CREATE OR REPLACE FUNCTION public._address_type(address text, city text, zip text)
RETURNS address_type
LANGUAGE plpgsql
AS $function$ DECLARE r address_type;
BEGIN
  r.address = address;
  r.city = city;
  r.zip = zip;
  RETURN r;
END;
$function$

创建此系统需要一些工作,仅适用于长时间系统。另一方面,它降低了未来维护工作的成本。

CREATE OR REPLACE FUNCTION public.fx(p person_type, a address_type)
RETURNS void
LANGUAGE plpgsql
AS $function$
BEGIN
  INSERT INTO tab(name, surname, address, city, zip)
    VALUES(p.name, p.surname, a.address, a.city, a.zip);
   -- ... some other logic
END;
$function$

现在,更多符号(符号组合)是可能的:

postgres=# SELECT fx(_person_type('Pavel','Stehule'),
postgres(#           _address_type('Skalice 12','Benesov', '25601'));
 fx 
----

(1 row)

构造函数有助于错误本地化:

postgres=# SELECT fx(_person_type('Pavel','Stehule'),
          _address_type('Skalice 12','Benesov', 25601));
ERROR:  function _address_type(unknown, unknown, integer) does not exist
LINE 2:           _address_type('Skalice 12','Benesov', 25601));
                  ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

答案 1 :(得分:2)

函数调用中的参数类型与函数定义中的参数类型不匹配。特别是,prm_default_billing_method_id应该是text,但是你传递的是整数2。您可以使用'2'2::textcast(2 as text)

此外,在您的函数中,第26行有一个拼写错误:set search_patch而不是set search_path