Home > Enterprise >  How to create random function using a stored procedure? PL/SQL
How to create random function using a stored procedure? PL/SQL

Time:11-22

I have a procedure that adds data

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

and I want to create a function that for each combination of customers and items to create an additional one at random entry in the table price.

How can I do that?

CodePudding user response:

Don't use a function, create a procedure and use INSERT ... SELECT with the CROSS JOIN of the customers and the items tables:

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;
/

Which, if you have the sample data:

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)
);

Then after:

BEGIN
  generate_random_prices();
END;
/

The prices table may (randomly) contain:

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

If you want to call your ADD_PRICE procedure then just take the same CROSS JOIN query and use a cursor loop:

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;
/

(But it will be more efficient to just use a single INSERT ... SELECT statement.)

db<.fiddle here

CodePudding user response:

UPD: Please note, I believe the idea from MT0 is better because you'll need only one insert statement. My solution is for the case when using add_price function is required

So, "each combination of customers and items" means you need a cartesian product:

select cust_id, item_id
  from customers
  cross join items;

For example if you had following data in "customers" and "items" table:

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

the query above would return:

cust_id item_id
1 1
1 2
2 1
2 2

Thus, all is left is to get random value. Use dbms_random.value for that

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;

The parameters for value are lowes_value and highest_value so the result will be between those numbers. You probably will need to set them somehow. And rounding will be needed too

  • Related