【问题标题】:You might need to add explicit type casts您可能需要添加显式类型转换
【发布时间】:2019-05-27 01:22:45
【问题描述】:

我正在尝试创建返回最后插入的 id 的函数,但在函数调用时显示错误: 请你帮我找出我的错误。

错误:函数 public.insert_voucher(integer, unknown, unknown, integer, integer, unknown) 不存在
第 1 行:选择 public.insert_voucher(1, 'P', '20180909', 1, 1, 'txt');

功能:

CREATE OR REPLACE FUNCTION public.insert_voucher(
     in_orgid smallint
    ,in_transtype character
    ,in_date character
    ,in_partnerid smallint
    ,in_quantity smallint
    ,in_remarks character varying)
  RETURNS integer AS
$BODY$
BEGIN
insert into 
public.transaction_header(
   org_id
  ,trans_type
  ,fiscal_year
  ,date
  ,partner_id
  ,quantity
  ,remarks
  ,create_by
  ,create_ts)
values (
   in_orgid
  ,in_transtype
  ,1819
  ,in_date
  ,in_partnerid
  ,in_quantity
  ,in_remarks
  ,1
  ,now())
returning trans_header_id;
END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 1;

表架构:

trans_header_id integer NOT NULL DEFAULT nextval('transaction_header_trans_header_id_seq'::regclass)
,org_id smallint NOT NULL
,trans_type character(1) NOT NULL DEFAULT 'P'::bpchar
,fiscal_year smallint NOT NULL DEFAULT '1819'::smallint
,date date NOT NULL
,partner_id smallint NOT NULL
,quantity smallint NOT NULL
,remarks character varying(100)
,create_by smallint NOT NULL
,create_ts timestamp without time zone NOT NULL DEFAULT now()
,update_by smallint
,update_ts timestamp without time zone
,CONSTRAINT transaction_header_pk PRIMARY KEY (trans_header_id)
,CONSTRAINT create_by FOREIGN KEY (create_by)
REFERENCES public.app_user (user_id) MATCH FULL
          ON UPDATE NO ACTION ON DELETE NO ACTION
,CONSTRAINT org_id FOREIGN KEY (org_id)
          REFERENCES public.organization (org_id) MATCH FULL
          ON UPDATE NO ACTION ON DELETE NO ACTION
,CONSTRAINT partner_id FOREIGN KEY (partner_id)
          REFERENCES public.partners (partner_id) MATCH FULL
          ON UPDATE NO ACTION ON DELETE NO ACTION
,CONSTRAINT update_by FOREIGN KEY (update_by)
          REFERENCES public.app_user (user_id) MATCH FULL
          ON UPDATE NO ACTION ON DELETE NO ACTION
,CONSTRAINT org_fy_transtype_transno UNIQUE (org_id, trans_type, fiscal_year)

参考@muistooshort 和@stickybit,我正在更新以前的函数。 希望它能提供更多的清晰度并返回所需的结果。

CREATE OR REPLACE FUNCTION public.insert_voucher(
    IN in_orgid smallint
    ,IN in_transtype character
    ,IN in_date date
    ,IN in_partnerid smallint
    ,IN in_quantity smallint
    ,IN in_remarks character varying
    ,OUT out_id smallint)
  RETURNS smallint AS
$BODY$
    BEGIN
    insert into 
    public.transaction_header(
       org_id
      ,trans_type
      ,fiscal_year
      ,date
      ,partner_id
      ,quantity
      ,remarks
      ,create_by
      ,create_ts)
    values (
       in_orgid
      ,in_transtype
      ,1819
      ,in_date
      ,in_partnerid
      ,in_quantity
      ,in_remarks
      ,1
      ,now())
    RETURNING trans_header_id
    INTO out_id;
    END
    $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 1;

【问题讨论】:

  • @muistooshort 这是转换为字符的日期格式 (YYYYMMDD)。
  • INSERT INTO transaction_header(org_id,trans_type,fiscal_year,date,partner_id,quantity,remarks,create_by,create_ts) values(1,'P','1819','20180909',1,1,'txt',1,now()) 语句将适用于相同的表架构。
  • @muistooshort 是的,我同意将输入更改为date 而不是character

标签: postgresql


【解决方案1】:

smallints 是问题所在。从integersmallint 的转换可能意味着丢失一些信息。引擎不会进行隐式强制转换,这样信息可能会丢失。因此它认为public.insert_voucher(integer, unknown, unknown, integer, integer, unknown) 不是一个选项。

如果您将数字显式转换为 smallint,则调用应该可以工作。

SELECT public.insert_voucher(1::smallint, 'P', '20180909', 1::smallint, 1::smallint, 'txt');

还有其他一些事情,例如为什么将日期作为字符串传递和'1819'::smallint(为什么首先传递字符串?)。一旦通话成功,可能会出现其他一些问题。但这超出了当前的问题。

【讨论】:

  • @muistooshort:我对此并不完全确定,但我有一些模糊的记忆,Postgres 忽略了函数签名中字符串值的长度参数。无论如何都要以text 的形式传递它。所以我相信这可能不是问题。但正如我所说,我不确定这一点。
  • @muistooshort:是的,我同意。日期应该是date
  • 谢谢@stickybit。您能否解释一下Insert CommandFunction command 之间的区别,为什么Function command 需要类型转换?
猜你喜欢
  • 2017-06-28
  • 2015-04-07
  • 2020-06-16
  • 2013-09-09
  • 2017-07-16
  • 2018-11-08
  • 1970-01-01
  • 2017-08-31
  • 2021-02-05
相关资源
最近更新 更多