如何使用PL/SQL在Oracle中创建包含随机数字段的表?

如何使用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

我需要创建一个包含随机列数的Oracle表以进行负载测试。我只想指定number类型的列数,VARCHAR2类型的列数等等,这些字段应该自动生成。此外,我将用随机数据填充表,我将使用dbms_random


我怎样才能做到这一点呢?

您可以自己生成这样的表

创建具有所需数据类型的表:

  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>