2010-09-06 14 views

Respuesta

9

"Sólo quiero especificar el número de columnas con tipo Number, número de columnas con el tipo VARCHAR2 etc y los campos debe generarse automáticamente."

El siguiente procedimiento hace justamente eso. Tenga en cuenta que es bastante básico; es posible que desee hacerlo más sofisticado, por ejemplo, variando la longitud de las columnas 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> 

Aquí está en acción:

SQL> exec bld_table ('T23', 2, 3, 0) 

PL/SQL procedure successfully completed. 

SQL> desc t23 
Name          Null? Type 
----------------------------------------- -------- ---------------------------- 
PK_COL         NOT NULL NUMBER 
COL_N1            NUMBER 
COL_N2            NUMBER 
COL_V1            VARCHAR2(30 CHAR) 
COL_V2            VARCHAR2(30 CHAR) 
COL_V3            VARCHAR2(30 CHAR) 

SQL> 

También podemos utilizar SQL dinámico para rellenar la tabla con filas de datos aleatorios.

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> 

Tenga en cuenta que la clave principal se rellena con el ROWNUM, por lo que es muy probable que falle si la tabla ya contiene filas.

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> 

Nuevamente, hay todo tipo de formas de mejorar la sofisticación de los datos.


Como un lado, el uso de este tipo de grupos de datos para la prueba de carga no siempre es una buena idea.Los problemas de rendimiento a menudo son causados ​​por desviaciones en la distribución de valores de datos que no se obtendrán con DBMS_RANDOM. Esto es particularmente cierto en algunas columnas de fechas, p. START_DATE - que tienden a agruparse en la vida real, pero el procedimiento anterior no generará ese patrón. Del mismo modo, al máximo las columnas varchar2 darán lugar a tablas que ocupan más espacio de almacenamiento de lo que ocuparán en la vida real.

En resumen, los datos generados al azar son mejores que nada, pero tenemos que entender sus debilidades.

+0

¡Exactamente lo que necesitaba! Gracias por la respuesta detallada. Estoy de acuerdo en que son limitaciones con los datos generados aleatoriamente. Limitaré la cantidad de aleatorización para datos que sé que serán similares. Esto debería ser posible para números y cadenas. Sin embargo, no estoy seguro de las fechas – Chandam

1

Puede generar dicha tabla usted mismo.

Crear una tabla con los tipos de datos requeridos:

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 

(Puede cambiar 1000 a los números de filas necesarias, y añadir tipos de datos requeridos)

Después de que se puede crear o rellenar las tablas con datos aleatorios de 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 
2

Dos enfoques

1) Escriba el código para generar archivos de texto que contengan los comandos CREATE TABLE que necesita para ejecutar y completar sus tablas, luego ejecútelos usando SQL * Plus.

2) El uso de SQL dinámico incrustado dentro de PL/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; 

También es posible usar 'CREATE TABLE AS SELECT' para llenar la mesa al mismo tiempo (ver otra respuesta).

Esto debería darle un buen punto de partida: no hay nada en el sistema que haga lo que quiera sin escribir código.

Cuestiones relacionadas