如何使用存储过程创建随机函数? PL/SQL

Posted

技术标签:

【中文标题】如何使用存储过程创建随机函数? PL/SQL【英文标题】:How to create random function using a stored procedure? PL/SQL 【发布时间】:2021-12-31 21:43:44 【问题描述】:

我有一个添加数据的程序

add_price (cust_id customers.id%type,
           items_id items.id%type,
           price number);

我想创建一个函数,为客户和项目的每个组合在表价格中随机创建一个额外的条目。

我该怎么做?

【问题讨论】:

我不明白你想做什么。您想添加另一条记录,但在什么条件下? @AliFidanli 我想从随机函数中调用 add_price(插入值)并为价格创建随机值。 【参考方案1】:

不要使用函数,而是创建一个过程并将INSERT ... SELECTcustomersitems 表的CROSS JOIN 一起使用:

CREATE PROCEDURE generate_random_prices
IS
BEGIN
  INSERT INTO prices (customer_id, item_id, price)
  SELECT c.customer_id,
         i.item_id,
         ROUND(DBMS_RANDOM.VALUE(0,100),2)
  FROM   customers c
         CROSS JOIN items i;
END generate_random_prices;
/

如果你有样本数据:

CREATE TABLE customers (customer_id PRIMARY KEY) AS
SELECT COLUMN_VALUE FROM TABLE(SYS.ODCINUMBERLIST(1,5,42));

CREATE TABLE items (item_id PRIMARY KEY) AS
SELECT COLUMN_VALUE FROM TABLE(SYS.ODCINUMBERLIST(1,3,61));

CREATE TABLE prices (
  customer_id REFERENCES customers(customer_id),
  item_id     REFERENCES items(item_id),
  price       NUMBER(4,2)
);

然后:

BEGIN
  generate_random_prices();
END;
/

prices 表可能(随机)包含:

CUSTOMER_ID ITEM_ID PRICE
1 1 38.91
1 3 39.74
1 61 67.28
5 1 13.92
5 3 48.17
5 61 70.21
42 1 90.33
42 3 5.7
42 61 40.37

如果您想调用您的 ADD_PRICE 过程,那么只需使用相同的 CROSS JOIN 查询并使用游标循环:

CREATE PROCEDURE generate_random_prices
IS
BEGIN
  FOR rw IN (SELECT c.customer_id,
                    i.item_id
             FROM   customers c
                    CROSS JOIN items i)
  LOOP
    ADD_PRICE(rw.customer_id, rw.item_id, ROUND(DBMS_RANDOM.VALUE(0,100),2));
  END LOOP;
END generate_random_prices;
/

(但只使用单个 INSERT ... SELECT 语句会更有效。)

db<.fiddle href="https://dbfiddle.uk/?rdbms=oracle_18&fiddle=c22bdb22d90d658cc3421e1957cfd5fe" rel="nofollow" target="_blank">here

【讨论】:

这正是我想要的......带有 add_price 程序的那个。但它返回我 --PLS-00402 选择游标列表中需要别名以避免第 4 行中的重复列。 @GEO 从问题中链接的 dbfiddle 可以看出,我的代码不会产生该错误。您需要调试您的代码并查看您所做的不同之处,然后您可以在互联网上搜索PLS-00402 并阅读导致该问题的原因,看看您是否可以解决它。如果您不知道您做了哪些不同的事情,我们无法为您提供帮助(最好是学习如何调试自己的代码)。【参考方案2】:

UPD:请注意,我相信 MT0 的想法更好,因为您只需要一个插入语句。我的解决方案是针对需要使用 add_price 函数的情况

因此,“客户和商品的每个组合”意味着您需要一个笛卡尔积:

select cust_id, item_id
  from customers
  cross join items;

例如,如果您在“客户”和“项目”表中有以下数据:

cust_id cust_name
1 A
2 B
item_id item_name
1 a
2 b

上面的查询会返回:

cust_id item_id
1 1
1 2
2 1
2 2

因此,剩下的就是获取随机值。为此使用 dbms_random.value

begin
  for q in (select cust_id, item_id from customers cross join items) loop
    add_price(q.cust_id, q.item_id, round(dbms_random.value(10, 1000), 2));
  end loop;
end;

值的参数是lowes_value 和highest_value,因此结果将介于这些数字之间。您可能需要以某种方式设置它们。也需要四舍五入

【讨论】:

以上是关于如何使用存储过程创建随机函数? PL/SQL的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL学习笔记_03_存储函数与存储过程

Oracle --- 存储过程函数包游标触发器

Oracle --- 存储过程函数包游标触发器

Oracle --- 存储过程函数包游标触发器

PL-SQL 存储函数和存储过程

PL/SQL轻量版——存储函数/存储过程