如何使用PL/SQL在Oracle中创建包含随机数字段的表?
我需要创建一个包含随机列数的Oracle表以进行负载测试。我只想指定number类型的列数,VARCHAR2类型的列数等等,这些字段应该自动生成。此外,我将用随机数据填充表,我将使用dbms_random如何使用PL/SQL在Oracle中创建包含随机数字段的表?,oracle,random,plsql,code-generation,Oracle,Random,Plsql,Code Generation,我需要创建一个包含随机列数的Oracle表以进行负载测试。我只想指定number类型的列数,VARCHAR2类型的列数等等,这些字段应该自动生成。此外,我将用随机数据填充表,我将使用dbms_random 我怎样才能做到这一点呢?您可以自己生成这样的表 创建具有所需数据类型的表: Create Table RandomTable AS Select dbms_random.string('A', 1) CharField, dbms_random.string('a
我怎样才能做到这一点呢?您可以自己生成这样的表 创建具有所需数据类型的表:
Create Table RandomTable
AS
Select dbms_random.string('A', 1) CharField,
dbms_random.string('a', 20) VarCharField,
TRUNC(dbms_random.value(0, 35000)) IntField,
dbms_random.value(0, 35000) NumberField,
Level SequenceField,
sysdate + dbms_random.value(-3500, 3500) DateField
from dual connect by level < 1000
创建随机表
作为
选择dbms_random.string('A',1)字符域,
dbms_random.string('a',20)VarCharField,
TRUNC(dbms_random.value(03500))IntField,
dbms_随机值(03500)NumberField,
级别字段,
sysdate+dbms_随机值(-3500,3500)日期字段
通过低于1000级的双连接
(您可以将1000更改为所需的行号,并添加所需的数据类型)
之后,您可以使用RandomTable中的随机数据创建或填充表
Create Table TestTable1
AS
SELECT CharField as a, NumberField as b
from RandomTable
INSERT INTO TestTable2(DateFrom, Quantity)
SELECT DateField, IntField
from RandomTable
Where SequenceField <= 500
创建表TestTable1
作为
选择CharField作为a,选择NumberField作为b
从随机表
插入TestTable2(日期、数量)
选择DateField,IntField
从随机表
其中SequenceField两种方法
1) 编写代码以生成包含运行和填充表所需的CREATE TABLE命令的文本文件,然后使用SQL*Plus执行这些命令
2) 使用内嵌在PL/SQL中的动态SQL-
PROCEDURE create_random_table
(pTableName IN VARCHAR2,
pNumberOfColumns IN INTEGER)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
lCommand VARCHAR2(32000);
BEGIN
lCommand :=
'CREATE TABLE '||pTableName||'(';
FOR i IN 1..pNumberOfColumns LOOP
append your column definition here
END LOOP;
lCommand := lCommand||';';
--
EXECUTE IMMEDIATE lCommand;
END;
您也可以使用“创建表格作为选择”来同时填充表格(请参阅其他答案)
这应该为您提供一个良好的起点—系统中没有任何东西不编写代码就可以完成您想要的任务
“我只想指定
具有类型编号的列,数量为
VARCHAR2等类型的列和
应生成字段
自动地。”
下面的过程就是这样做的。注意,它是相当基本的;您可能希望使其更加复杂,例如通过改变varchar2列的长度:
SQL> create or replace procedure bld_table
2 ( p_tab_name in varchar2
3 , no_of_num_cols in pls_integer
4 , no_of_var_cols in pls_integer
5 , no_of_date_cols in pls_integer
6 )
7 as
8 begin
9 execute immediate 'create table '||p_tab_name||' ('
10 ||' pk_col number not null'
11 ||', constraint '||p_tab_name||'_pk primary key (pk_col) using index)';
12 << numcols >>
13 for i in 1..no_of_num_cols loop
14 execute immediate 'alter table '||p_tab_name||' add '
15 ||' col_n'||trim(to_char(i))||' number';
16 end loop numcols;
17 << varcols >>
18 for i in 1..no_of_var_cols loop
19 execute immediate 'alter table '||p_tab_name||' add '
20 ||' col_v'||trim(to_char(i))||' varchar2(30)';
21 end loop varcols;
22 << datcols >>
23 for i in 1..no_of_date_cols loop
24 execute immediate 'alter table '||p_tab_name||' add '
25 ||' col_d'||trim(to_char(i))||' date';
26 end loop datcols;
27 end bld_table;
28 /
Procedure created.
SQL>
我们还可以使用动态SQL用随机数据行填充表
SQL> create or replace procedure pop_table
2 ( p_tab_name in varchar2
3 , p_no_of_rows in pls_integer
4 )
5 as
6 stmt varchar2(32767);
7 begin
8 stmt := 'insert into '||p_tab_name
9 || ' select rownum ';
10 for r in ( select column_name
11 , data_type
12 , data_length
13 from user_tab_columns
14 where table_name = p_tab_name
15 and column_name != 'PK_COL' )
16 loop
17 case r.data_type
18 when 'VARCHAR2' then
19 stmt := stmt ||', dbms_random.string(''a'', '||r.data_length||')';
20 when 'NUMBER' then
21 stmt := stmt ||', dbms_random.value(0, 1000)';
22 when 'DATE' then
23 stmt := stmt ||', sysdate + dbms_random.value(-1000, 0)';
24 end case;
25 end loop;
26 stmt := stmt || ' from dual connect by level <= '||p_no_of_rows;
27 execute immediate stmt;
28 end pop_table;
29 /
Procedure created.
SQL>
同样,有各种各样的方法来提高数据的复杂性
另外,使用这些类型的数据池进行负载测试并不总是一个好主意。性能问题通常是由数据值分布中的偏差引起的,这是DBMS_RANDOM无法获得的。对于某些日期列(例如START_date),情况尤其如此,这些列在现实生活中往往会聚集在一起,但上述过程不会生成这种模式。类似地,将varchar2列最大化将导致表占用比实际使用情况下更多的存储空间
简言之,随机生成的数据总比没有好,但我们需要了解它的弱点 正是我需要的!谢谢你的详细回答。我同意随机生成数据的局限性。我将限制我知道相似数据的随机化数量。这对于数字和字符串应该是可能的。但不确定日期
SQL> create or replace procedure pop_table
2 ( p_tab_name in varchar2
3 , p_no_of_rows in pls_integer
4 )
5 as
6 stmt varchar2(32767);
7 begin
8 stmt := 'insert into '||p_tab_name
9 || ' select rownum ';
10 for r in ( select column_name
11 , data_type
12 , data_length
13 from user_tab_columns
14 where table_name = p_tab_name
15 and column_name != 'PK_COL' )
16 loop
17 case r.data_type
18 when 'VARCHAR2' then
19 stmt := stmt ||', dbms_random.string(''a'', '||r.data_length||')';
20 when 'NUMBER' then
21 stmt := stmt ||', dbms_random.value(0, 1000)';
22 when 'DATE' then
23 stmt := stmt ||', sysdate + dbms_random.value(-1000, 0)';
24 end case;
25 end loop;
26 stmt := stmt || ' from dual connect by level <= '||p_no_of_rows;
27 execute immediate stmt;
28 end pop_table;
29 /
Procedure created.
SQL>
SQL> exec pop_table('T23', 4)
PL/SQL procedure successfully completed.
SQL> select * from t23
2 /
PK_COL COL_N1 COL_N2 COL_V1 COL_V2 COL_V3
---------- ---------- ---------- ------------------------------ ----------------------------- ------------------------------
1 913.797432 934.265814 NUtxjLoRQMCTLNMPKVGbTZwJeYaqnXTkCcWu WFRSHjXdLfpgVYOjzrGrtUoX jIBSoYOhSdhRFeEeFlpAxoanPabvwK
2 346.879815 104.800387 NTkvIlKeJWybCTNEdvsqJOKyidNkjgngwRNN PPIOInbzInrsVTmFYcDvwygr RyKFoMoSiWTmjTqRBCqDxApIIrctPu
3 93.1220275 649.335267 NTUxzPRrKKfFncWaeuzuyWzapmzEGtAwpnjj jHILMWJlcMjnlboOQEIDFTBG JRozyOpWkfmrQJfbiiNaOnSXxIzuHk
4 806.709357 857.489387 ZwLLkyINrVeCkUpznVdTHTdHZnuFzfPJbxCB HnoaErdzIHXlddOPETzzkFQk dXWTTgDsIeasNHSPbAsDRIUEyPILDT
4 rows selected.
SQL>