Reputation: 39
I have two tables, one is Clients
where i have primary key: ClientID
(integer type). The other table is Orders
where I have foreign key: idClient
. I want to generate random data into Orders
but also idClient
should be ClientID
numbers from Clients
.
Here's what I wrote:
INSERT INTO Orders
SELECT level AS OrderID,
(SELECT * FROM (SELECT ClientID FROM Clients ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM = 1) AS idClient,
DBMS_RANDOM.string('L',TRUNC(DBMS_RANDOM.value(2,50))) AS ProductName,
TRUNC(SYSDATE + DBMS_RANDOM.value(0,366)) AS Date,
TRUNC(DBMS_RANDOM.value(15,2000)) AS Price
FROM dual
CONNECT BY level <= 200;
COMMIT;
The problem is that when I look at generated records in Orders
, I have the same number in idClient
in every row for example 24
in each row. I want there various numbers selected from ClientID
.
How to fix it??
Thank you in advance.
Upvotes: 1
Views: 1899
Reputation: 2252
You could CROSS JOIN the client table as often as you need to get enough sample rows, SELECT (valid) ids from this query, and then add all other random columns in an outer query. Example (see also dbfiddle):
Tables
create table clients ( id, name )
as
select 101, 'client_101' from dual union all
select 202, 'client_202' from dual union all
select 303, 'client_303' from dual union all
select 404, 'client_404' from dual union all
select 505, 'client_505' from dual union all
select 606, 'client_606' from dual union all
select 707, 'client_707' from dual union all
select 808, 'client_808' from dual union all
select 909, 'client_909' from dual ;
alter table clients add constraint pkey_clients primary key ( id ) ;
create table orders (
id number primary key
, idclient number references clients ( id )
, productname varchar2( 256 )
, orderdate date
, price number( 12, 2 )
);
INSERT (from SELECT)
insert into orders ( id, idclient, productname, orderdate, price )
select
rownum
, idclient
, dbms_random.string( 'L', trunc( dbms_random.value( 2, 50 ) ) ) as productname
, trunc( sysdate + dbms_random.value( 0, 366 ) ) as orderdate
, trunc( dbms_random.value( 15, 2000 ) ) as price
from
(
select
C1.id idclient
from clients C1, clients C2, clients C3 -- cross join -> 9*9*9 rows
order by dbms_random.value
) where rownum <= 200 ; -- stop inserting at row 200
200 rows inserted.
Table ORDERS (query)
SQL> select *
2 from orders
3 order by id ;
ID IDCLIENT PRODUCTNAME ORDERDATE PRICE
1 404 kiowzgecnajoyxdioxz 10-APR-19 295
2 707 tnzdcsvpjlpoujpdndyqxp 04-OCT-19 1552
3 404 sqiwohwxkmqpuwoocoeyoaqmnoxbcfogqmyhcmhwc 25-DEC-18 809
4 808 msbgnuwdzl 09-FEB-19 526
5 303 fyqmldaypwx 23-FEB-19 1669
6 101 etodatstbjtfcqwnvswyp 26-SEP-19 869
7 101 auhcvnmlgjzetdbhozdtdirwqmvnhghfnvfvhfehstkv 31-JUL-19 1847
8 303 krartgctrgcpcuuquffaajgphsnoxgmhimmgnjbwu 24-SEP-19 1628
9 404 bzvcyylvdelskogqmpbztowqewnodazcjbrgqykbkxzsbs 13-SEP-19 71
10 909 cwnmrogvjqcykxmfdybnqrxnaruhtqcyjcqrnifkiipjhnq 04-NOV-18 1837
11 909 ojpyldoiukfiusssqyfrqlgqwyfnoyljqioobx 20-MAR-19 861
12 808 tqzdab 13-JAN-19 597
...
...
...
UPDATE
If there are several "source tables" you want to get the IDs from (as stated in your comment), just use all relevant table names in the cross join. Example:
-- 3 parent tables ("sources" of ids)
create table src1 ( id number primary key ) ;
insert into src1( id )
select level + 3000 as id
from dual connect by level <= 5 ;
create table src2 ( id number primary key ) ;
insert into src2( id )
select level + 4000 as id
from dual connect by level <= 5 ;
create table src3 ( id number primary key ) ;
insert into src3( id )
select level + 5000 as id
from dual connect by level <= 5 ;
-- 1 child table with 3 foreign key constraints
create table dest (
id number generated always as identity start with 1000 primary key
, src1id number references src1( id )
, src2id number references src2( id )
, src3id number references src3( id )
, shipmentstatus number not null
check( shipmentstatus in ( 0, 1 ) )
);
Query / insert
insert into dest( src1id, src2id, src3id, shipmentstatus )
select src1id, src2id, src3id, mod( src1id, 2 ) shipmentstatus
-- generate more data as required
-- , dbms_random.string( 'L', trunc( dbms_random.value( 2, 30 ) ) ) as productname
-- , trunc( sysdate + dbms_random.value( 0, 366 ) ) as orderdate
-- , trunc( dbms_random.value( 15, 2000 ) ) as price
from (
select
A.id src1id
, B.id src2id
, C.id src3id
from src1 A, src2 B, src3 C
order by dbms_random.value
)
where rownum <= 200
;
Result
select * from dest fetch first 12 rows only ;
ID SRC1ID SRC2ID SRC3ID SHIPMENTSTATUS
1000 3004 4005 5002 0
1001 3001 4004 5001 1
1002 3004 4001 5002 0
1003 3001 4003 5003 1
1004 3004 4005 5005 0
1005 3003 4001 5003 1
1006 3003 4003 5001 1
1007 3001 4002 5003 1
1008 3004 4001 5004 0
1009 3005 4002 5003 1
1010 3004 4005 5003 0
1011 3002 4002 5001 0
If the cross join ( ... from src1, src2, src3 ... ) does not give you enough rows, just run the query again.
Upvotes: 2