Проблема с функцией сборки в postgresql - PullRequest
0 голосов
/ 04 января 2019
    -- Function: adempiere.qtyondateorg2(integer, timestamp with time zone, character varying)

-- DROP FUNCTION adempiere.qtyondateorg2(integer, timestamp with time zone, character varying);

CREATE OR REPLACE FUNCTION adempiere.qtyondateorg2(
    product_id integer,
    indate timestamp with time zone,
    org_id character varying)
  RETURNS numeric AS
$BODY$
DECLARE
    Quantity        NUMERIC := 0;
    vP              NUMERIC := 0;
BEGIN

  SELECT Aux.M_Product_ID, SUM(Aux.QtyOnHand) AS QtyOnHand 
    INTO vP, Quantity FROM

  (SELECT DISTINCT    '1', s.M_Product_ID, SUM(s.QtyOnHand) AS QtyOnHand, l.M_Warehouse_ID, l.M_Locator_ID
          FROM    M_Storage s
    INNER JOIN    M_Locator l ON s.M_Locator_ID = l.M_Locator_ID
    INNER JOIN    M_Warehouse w ON l.M_Warehouse_ID=w.M_Warehouse_ID
         WHERE    s.M_Product_ID = Product_ID
         AND      w.lbr_WarehouseType NOT LIKE '3RD'
        AND l.AD_Org_ID IN (org_id)
      GROUP BY    s.M_Product_ID, l.M_Warehouse_ID, l.M_Locator_ID, l.AD_Org_ID
UNION
        SELECT    '2', t.M_Product_ID, SUM(t.MovementQty) * -1 AS QtyOnHand, l.M_Warehouse_ID, t.M_Locator_ID
          FROM    M_Transaction t
    INNER JOIN    M_Locator l ON t.M_Locator_ID = l.M_Locator_ID
    INNER JOIN    M_Warehouse w ON l.M_Warehouse_ID=w.M_Warehouse_ID
         WHERE    TRUNC(t.MovementDate) >= TRUNC(InDate)
           AND    w.lbr_WarehouseType NOT LIKE '3RD'
           AND    t.M_Product_ID = Product_ID
           AND l.AD_Org_ID IN ( org_id )
      GROUP BY    t.M_Product_ID, l.M_Warehouse_ID, t.M_Locator_ID, l.AD_Org_ID) Aux

      GROUP BY M_Product_ID;

      IF (Quantity IS NULL) THEN
    Quantity := 0;
      END IF;

      RETURN Quantity;
END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION adempiere.qtyondateorg2(integer, timestamp with time zone, character varying)
  OWNER TO adempiere; 

У меня проблема в следующей функции, в параметре AD_Org_ID я хотел бы передать в виде строки, как показано ниже:

  select adempiere.qtyondateorg2 (2045480, '31/12/2018',' 2000002, 2000003');

Однако я получаю следующую ошибку:

ОШИБКА: оператор не существует: числовой = символ меняется ЛИНИЯ 10: И l.AD_Org_ID IN (org_id)

СОВЕТ: ни один оператор не соответствует заданному имени и типу (аргументам) аргумента. Возможно, вам придется добавить явные приведения типов.

Помогите ли вы правильно сформировать функцию? Спасибо

1 Ответ

0 голосов
/ 04 января 2019

Вы не можете использовать оператор IN следующим образом:

create or replace function wrong_func(org_id varchar)
returns boolean language plpgsql as $$
declare
    ad_org_id numeric = 1;
begin
    -- this raises an error as ad_org_id is numeric and org_id is varchar
    return ad_org_id in (org_id);
end $$;

select wrong_func('1,2,3');

ERROR:  operator does not exist: numeric = character varying
LINE 1: SELECT ad_org_id in (org_id)
                         ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.  

Используйте числовой массив в качестве аргумента следующим образом:

create or replace function correct_func(org_id numeric[])
returns boolean language plpgsql as $$
declare
    ad_org_id numeric = 1;
begin
    return ad_org_id = any(org_id);
end $$;

select correct_func('{1,2,3}')

 correct_func 
--------------
 t
(1 row)
...