在oracle 11g中生成样本数据

时间:2015-10-08 09:56:33

标签: oracle plsql

我有以下程序的问题,它根本不选择随机的街道和城镇。问题在于

streets(SYS.DBMS_RANDOM.VALUE(1,50)) 

towns(SYS.DBMS_RANDOM.VALUE(1,50)) 

看起来是random.value只评估一次,如何让它选择varray的随机元素?

CREATE OR REPLACE PROCEDURE GENERATE_ADDRESSES AS
    type streetType is varray(50) of addresses.street%TYPE;
    streets streetType:= streetType('Rebel Loop East', 'Everleigh Rise', 'Double Oak,Pig Mount West', 'Byam Byway', 'South Damour Trail', 'Chart Hill Northwest', 'West Down Turnpike', 'Southeast Lawyers Hill Mount',
    'East Jibbon Road', 'Old Browns Valley Viaduct', 'Queensbury Viaduct', 'Northeast Hards Plaza', 'Northwest Cushing Promenade', 'North Queens Wood', 'South Oakton Plantation', 'East Redeker Terrace',
    'Stanbaugh Mount', 'Huse Nook', 'East Savine Grade', 'Bardo Manor', 'West Mina Rosa Place', 'West Oldarker Mall', 'West Oakgrove Lane', 'Woodleigh Row', 'Southwest Stoney Ridge Passage',
    'Cucumber Mews', 'Stoffa Trace North', 'West Echo Bay Alley', 'North Monkhams Terrace', 'Weller Grove West', 'Estate Walk', 'Doneraile Rise', 'North Yunga Burra Manor', 'Boundaries Square', 'Windsor Hill Row West',
    'South Silver Maple Close', 'West Back Westminster', 'East Bibsworth Causeway', 'Widdop Dell', 'Sawyer Hill', 'East Minehurst Street', 'East Ecclesbridge Close', 'North Clouston Court', 'Southwest Towradgi Alley',
    'Northeast Barkdoll Promenade', 'Southwest Icklingham Quay', 'North Fanum Quadrant', 'Nerbonne Croft', 'West Montee Alley', 'East Burra Street');

    type townType is varray(50) of addresses.town%TYPE;
    towns townType:= townType('Linland','Havenmoor','Fallbank','Marshbush','Whitenesse','Crystalfort','Dorhaven','Spellhall','Northbell','Westermerrow','Butterbeach','Fairbarrow','Violetbush','Westbeach','Landness','Rosemaple','Lochbush',
'Coastfield','Westmarsh','Golddale','Violetford','Elfacre','Brightmill','Bypine','Starryfox','Barrowmeadow','Ashbridge','Swynpond','Eribourne','Wintermill','Eribourne','Bridgebeach',
'Roselyn','Summerwinter','Fairviolet','Ashvale','Dordale','Osthaven','Deephaven','Whiteflower','Welledge','Snowbeach','Marblenesse','Witchnesse','Bluewell','Shorelake','Coldfalcon','Strongbush','','Freyholt');

    TYPE Addresses_type IS TABLE OF addresses%ROWTYPE INDEX BY BINARY_INTEGER;
    adb Addresses_type;
  BEGIN
    --fill streets and towns varrays
    insert into addresses(id, street, streetNo, town, countries_id)
    select rownum, streets(SYS.DBMS_RANDOM.VALUE(1,50)), floor(SYS.DBMS_RANDOM.VALUE(1,10000)) || '/' || floor(SYS.DBMS_RANDOM.VALUE(1,1000)), towns(SYS.DBMS_RANDOM.VALUE(1,50)), SYS.DBMS_RANDOM.VALUE(1,500)
    from dual
    connect by level <= 500;
  END GENERATE_ADDRESSES;
/

2 个答案:

答案 0 :(得分:2)

towns()和streets()是构造函数,但它们只是函数。我不确切地知道为什么会出现这种情况(也许它与通过双重内部工作的连接有关),但即使docs警告你也不能确定在一个函数中调用多少次函数SQL语句:

Invoking Stored PL/SQL Functions from SQL Statements

  

因为SQL是一种声明性语言,而不是命令式(或   程序性的)一,你不知道一个函数调用了多少次   即使函数是用PL / SQL编写的,SQL语句也会运行   命令式语言。如果您的应用程序需要函数   执行了一定次数,不要从a调用该函数   SQL语句。改为使用光标。

     

例如,如果您的应用程序要求调用函数   对于每个选定的行,然后打开一个光标,从中选择行   游标,并为每一行调用函数。这种技术保证   对函数的调用次数是获取的行数   从光标。

因此,解决方法是为每行调用dbms_random包多次:

for k in (select level as lev from dual connect by level <= 500)
loop
 insert into addresses(
   id, 
   street, 
   streetNo, 
   town, 
   countries_id
   )
values 
(
  k.lev, 
  streets(SYS.DBMS_RANDOM.VALUE(1,50)), 
  floor(SYS.DBMS_RANDOM.VALUE(1,10000)) || '/' || floor(SYS.DBMS_RANDOM.VALUE(1,1000)), 
  towns(SYS.DBMS_RANDOM.VALUE(1,50)), 
  SYS.DBMS_RANDOM.VALUE(1,500)
);
end loop;

稍后编辑:

这与dbms_random包无关。例如:

declare 
type townType is varray(50) of varchar2(1000);
    towns townType:= townType('Linland','Havenmoor','Fallbank','Marshbush','Whitenesse','Crystalfort','Dorhaven','Spellhall','Northbell','Westermerrow','Butterbeach','Fairbarrow','Violetbush','Westbeach','Landness','Rosemaple','Lochbush',
'Coastfield','Westmarsh','Golddale','Violetford','Elfacre','Brightmill','Bypine','Starryfox','Barrowmeadow','Ashbridge','Swynpond','Eribourne','Wintermill','Eribourne','Bridgebeach',
'Roselyn','Summerwinter','Fairviolet','Ashvale','Dordale','Osthaven','Deephaven','Whiteflower','Welledge','Snowbeach','Marblenesse','Witchnesse','Bluewell','Shorelake','Coldfalcon','Strongbush','','Freyholt');
v  varchar2(2000);

begin

   dbms_output.put_line('start!');

   select listagg(towns(level+1), ',') within group (order by 1) 
   into v 
   from dual
   connect by level < 5;

   dbms_output.put_line(v);

end loop;
end;
/

输出:

Linland,Linland,Linland,Linland

答案 1 :(得分:1)

我的建议是,如果您使用Toad for oracle工具,那么您可以选择使用随机值生成数百万个样本数据,您可以指定seq,varchar长度,数字长度等... 另一个主要优点是你可以分别将fk和pk关系映射到子表和父表。

GOTO schema_browser&gt;&gt;表&gt;&gt;右键单击所选表格并单击生成数据并选择限制并继续执行您的要求