【问题标题】:How can i fix a PLS-00306 ERROR inpl/sql?如何修复 pl/sql 中的 PLS-00306 错误?
【发布时间】:2023-04-04 19:11:01
【问题描述】:

我希望我的函数价格数据从客户那里获取 ID,并为每件商品制定特价。 示例:

  1. cust_id | item_id |价格
  2. 30 14 11
  3. 30 25 4
  4. 31 14 12
  5. 31 25 6
CREATE OR REPLACE FUNCTION PRICE_DATA(
        P_CUST_DATA_ID CUSTOMERS.CUSTOMERS_ID%TYPE,
        P_ITEMS_DATA_ID ITEMS.ITEMS_ID%TYPE)
   RETURN NUMBER AS
        L_PRICE NUMBER;
BEGIN
    dbms_random.seed(1000);
      FOR i IN(SELECT CUSTOMERS_ID FROM CUSTOMERS) LOOP
        FOR i IN(SELECT ITEMS_ID FROM ITEMS) LOOP
           L_PRICE := ADD_PRICELIST(P_CUST_DATA_ID,
                                                P_ITEMS_PRIC_ID,
                                                ROUND(dbms_random.value(0,10),3)); 
        END LOOP;
      END LOOP;
 RETURN L_PRICE;    
END PRICE_DATA;

我运行这个脚本:

DECLARE
 L_PRICE_ID NUMBER;

BEGIN 
  DELETE FROM PRICE;
   L_PRICE_ID := PRICE_DATA;
END;

我在价格数据中收到 PLS-00306 错误

【问题讨论】:

  • PLS-00306:参数数量或类型错误。您在此处调用函数 PRICE_DATA:L_PRICE_ID := PRICE_DATA;。该函数虽然定义了两个参数P_CUST_DATA_IDP_ITEMS_DATA_ID。所以你必须打一个像L_PRICE_ID := PRICE_DATA(123, 456);这样的电话。
  • 您为什么要遍历所有客户和所有商品以获得客户/商品组合的价格?

标签: sql oracle plsql


【解决方案1】:

在你的函数中,你有P_ITEMS_PRIC_ID 它应该是P_ITEMS_DATA_ID。您可能也不想同时调用两个行变量i


假设您的 ADD_PRICELIST 函数没有副作用(它不应该),您可以将其重写为:

CREATE OR REPLACE FUNCTION PRICE_DATA(
  P_CUST_DATA_ID  IN CUSTOMERS.CUSTOMERS_ID%TYPE,
  P_ITEMS_DATA_ID IN ITEMS.ITEMS_ID%TYPE
)
  RETURN NUMBER
AS
  L_PRICE NUMBER;
BEGIN
  dbms_random.seed(1000);
  SELECT ADD_PRICELIST(
           p_cust_data_id,
           p_items_data_id,
           ROUND(dbms_random.value(0,10),3)
         )
  INTO   L_PRICE
  FROM   customers c
         CROSS JOIN items i
  ORDER BY c.customers_id DESC, i.items_id DESC
  FETCH FIRST ROW ONLY;
    
  RETURN L_PRICE;    
END PRICE_DATA;
/

但这似乎有点矫枉过正,因为您不使用表中的任何值,并且实际上只是检查每个表中是否存在至少一行(并且多次调用ADD_PRICELIST 效率低下)然后您可以将其简化为仅检查行存在,然后调用一次函数:

CREATE OR REPLACE FUNCTION PRICE_DATA(
  P_CUST_DATA_ID  IN CUSTOMERS.CUSTOMERS_ID%TYPE,
  P_ITEMS_DATA_ID IN ITEMS.ITEMS_ID%TYPE
)
  RETURN NUMBER
AS
  L_PRICE  NUMBER;
  l_exists NUMBER(1,0);
BEGIN
  dbms_random.seed(1000);
  SELECT CASE
         WHEN EXISTS(SELECT 1 FROM customers)
         AND  EXISTS(SELECT 1 FROM items)
         THEN 1
         ELSE 0
         END
  INTO   l_exists
  FROM  DUAL;

  IF l_exists = 1 THEN
    l_price := ADD_PRICELIST(
                 p_cust_data_id,
                 p_items_data_id,
                 ROUND(dbms_random.value(0,10),3)
               );
  END IF;
    
  RETURN L_PRICE;    
END PRICE_DATA;
/

那么你需要在调用函数的时候指定所有的参数:

DECLARE
  L_PRICE_ID NUMBER;
BEGIN 
  --DELETE FROM PRICE;
  L_PRICE_ID := PRICE_DATA(3.14159, 2.71828);
  DBMS_OUTPUT.PUT_LINE(l_price_id);
END;
/

db小提琴here

【讨论】:

    猜你喜欢
    • 2014-06-25
    • 2022-12-02
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多