基于ORACLE数据库的循环建表及循环创建存储过程的SQL语句实现

一、概述

在实际的软件开发项目中,我们经常会遇到需要创建多个相同类型的数据库表或存储过程的时候。例如,如果按照身份证号码的尾号来分表,那么就需要创建10个用户信息表,尾号相同的用户信息放在同一个表中。

对于类型相同的多个表,我们可以逐个建立,也可以采用循环的方法来建立。与之相对应的,可以用一个存储过程实现对所有表的操作,也可以循环建立存储过程,每个存储过程实现对某个特定表的操作。

本文中,我们建立10个员工信息表,每个表中包含员工工号(8位)和年龄字段,以工号的最后一位来分表。同时,我们建立存储过程实现对员工信息的插入。本文中的SQL语句基于ORACLE数据库实现。

二、一般的实现方式

在该实现方式中,我们逐个建立员工信息表,并在一个存储过程实现对所有表的操作。具体SQL语句如下:

建表语句:

-- tb_employeeinfo0
begin
    execute immediate ‘drop table tb_employeeinfo0 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo0
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo0 on tb_employeeinfo0(employeeno);

prompt ‘create table tb_employeeinfo0 ok‘;
commit;

-- tb_employeeinfo1
begin
    execute immediate ‘drop table tb_employeeinfo1 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo1
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo1 on tb_employeeinfo1(employeeno);

prompt ‘create table tb_employeeinfo1 ok‘;
commit;

-- tb_employeeinfo2
begin
    execute immediate ‘drop table tb_employeeinfo2 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo2
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo2 on tb_employeeinfo2(employeeno);

prompt ‘create table tb_employeeinfo2 ok‘;
commit;

-- tb_employeeinfo3
begin
    execute immediate ‘drop table tb_employeeinfo3 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo3
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo3 on tb_employeeinfo3(employeeno);

prompt ‘create table tb_employeeinfo3 ok‘;
commit;

-- tb_employeeinfo4
begin
    execute immediate ‘drop table tb_employeeinfo4 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo4
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo4 on tb_employeeinfo4(employeeno);

prompt ‘create table tb_employeeinfo4 ok‘;
commit;

-- tb_employeeinfo5
begin
    execute immediate ‘drop table tb_employeeinfo5 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo5
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo5 on tb_employeeinfo5(employeeno);

prompt ‘create table tb_employeeinfo5 ok‘;
commit;

-- tb_employeeinfo6
begin
    execute immediate ‘drop table tb_employeeinfo6 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo6
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo6 on tb_employeeinfo6(employeeno);

prompt ‘create table tb_employeeinfo6 ok‘;
commit;

-- tb_employeeinfo7
begin
    execute immediate ‘drop table tb_employeeinfo7 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo7
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo7 on tb_employeeinfo7(employeeno);

prompt ‘create table tb_employeeinfo7 ok‘;
commit;

-- tb_employeeinfo8
begin
    execute immediate ‘drop table tb_employeeinfo8 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo8
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo8 on tb_employeeinfo8(employeeno);

prompt ‘create table tb_employeeinfo8 ok‘;
commit;

-- tb_employeeinfo9
begin
    execute immediate ‘drop table tb_employeeinfo9 cascade constraints‘;
    exception when others then commit;
end;

/
create table tb_employeeinfo9
(
    employeeno      varchar2(10)  not null,         -- employee number
    employeeage     int           not null          -- employee age
);
create unique index idx1_tb_employeeinfo9 on tb_employeeinfo9(employeeno);

prompt ‘create table tb_employeeinfo9 ok‘;
commit;

存储过程创建语句:

create or replace procedure pr_insertdata
(
    v_employeeno   in   varchar2,
    v_employeeage  in   int
)
as
    v_employeecnt     int;
    v_tableindex      varchar2(2);

begin
    v_tableindex     := substr(v_employeeno, length(v_employeeno), 1);

    if v_tableindex = ‘0‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo0 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo0(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘1‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo1 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo1(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘2‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo2 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo2(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘3‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo3 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo3(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘4‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo4 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo4(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘5‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo5 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo5(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘6‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo6 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo6(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘7‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo7 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo7(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘8‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo8 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo8(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    elsif v_tableindex = ‘9‘ then
    begin
        select count(*) into v_employeecnt from tb_employeeinfo9 where employeeno = v_employeeno;
        if v_employeecnt > 0 then       -- the employeeno is already in DB
        begin
            return;
        end;
        else                            -- the employeeno is not in DB
        begin
            insert into tb_employeeinfo9(employeeno, employeeage) values(v_employeeno, v_employeeage);
        end;
        end if;
    end;
    end if;
    commit;

exception when others then
    begin
        rollback;
        return;
    end;
end;
/
prompt ‘create procedure pr_insertdata ok‘

三、循环创建的实现方式

在该实现方式中,我们采用循环的方法建立员工信息表及存储过程。具体SQL语句如下:

建表语句:

-- tb_employeeinfo0~9
begin
     declare i int;tmpcount int;tbname varchar2(50);strsql varchar2(1000);
     begin
         i:=0;
         while i<10 loop
         begin
             tbname := ‘tb_employeeinfo‘||to_char(i);
             i := i+1;

             select count(1) into tmpcount from user_tables where table_name = Upper(tbname);
             if tmpcount>0 then
             begin
                 execute immediate ‘drop table ‘||tbname;
             commit;
             end;
             end if;
             strsql := ‘create table ‘||tbname||
             ‘(
                  employeeno      varchar2(10)  not null,         -- employee number
                  employeeage     int           not null          -- employee age
              )‘;
             execute immediate strsql;
             strsql := ‘begin
                  execute immediate ‘‘drop index idx1_‘||tbname || ‘ ‘‘‘
                  || ‘;exception when others then null;
                  end;‘;
             execute immediate strsql;

             execute immediate ‘create unique index idx1_‘||tbname||‘ on ‘||tbname||‘(employeeno)‘;

         end;
         end loop;
     end;
end;
/

存储过程创建语句:

begin
    declare v_i int;v_procname varchar(50);v_employeeinfotbl varchar(50);strsql varchar(4000);
begin
    v_i := 0;
    while v_i < 10 loop
        v_procname        := ‘pr_insertdata‘||substr(to_char(v_i),1,1);
        v_employeeinfotbl := ‘tb_employeeinfo‘||substr(to_char(v_i),1,1);

        v_i := v_i + 1;
        strsql := ‘create or replace procedure ‘||v_procname||‘(
            v_employeeno   in   varchar2,
            v_employeeage  in   int
        )
        as
            v_employeecnt     int;

        begin
            select count(*) into v_employeecnt from ‘||v_employeeinfotbl||‘ where employeeno = v_employeeno;
            if v_employeecnt > 0 then       -- the employeeno is already in DB
            begin
                return;
            end;
            else                            -- the employeeno is not in DB
            begin
                insert into ‘||v_employeeinfotbl||‘(employeeno, employeeage) values(v_employeeno, v_employeeage);
            end;
            end if;
            commit;
        exception when others then
            begin
                rollback;
                return;
            end;
        end;‘;
        execute immediate strsql;
    end loop;
    end;
end;
/

四、总结

当相同类型的表的个数较多时(如有上百个),显然用循环创建的实现方式可以节约大量的工作时间,提高工作效率。但是,在使用该方法的时候,要特别仔细,尤其要注意单引号的使用,避免为了省事而引入代码逻辑问题。



本人微信公众号:zhouzxi,请扫描以下二维码:

时间: 2024-07-30 13:50:52

基于ORACLE数据库的循环建表及循环创建存储过程的SQL语句实现的相关文章

点评阿里JAVA手册之MySQL数据库 (建表规约、索引规约、SQL语句、ORM映射)

下载原版阿里JAVA开发手册  [阿里巴巴Java开发手册v1.2.0] 本文主要是对照阿里开发手册,注释自己在工作中运用情况. 本文内容:MySQL数据库 (建表规约.索引规约.SQL语句.ORM映射) 本文难度系数为三星(★★★) 本文为第四篇 第一篇 点评阿里JAVA手册之编程规约(命名风格.常量定义.代码风格.控制语句.注释规约) 第二篇 点评阿里JAVA手册之编程规约(OOP 规约 .集合处理 .并发处理 .其他) 第三篇 点评阿里JAVA手册之异常日志(异常处理 日志规约 ) 第四篇

基于ORACLE建表和循环回路来创建数据库存储过程SQL语句来实现

一个.概要 在实际的软件开发项目.我们经常会遇到需要创造更多的相同类型的数据库表或存储过程时,.例如.假设按照尾号点表的ID号,然后,你需要创建10用户信息表,的用户信息放在同一个表中. 对于类型同样的多个表,我们能够逐个建立,也能够採用循环的方法来建立.与之相相应的,能够用一个存储过程实现对全部表的操作.也能够循环建立存储过程,每一个存储过程实现对某个特定表的操作. 本文中,我们建立10个员工信息表.每一个表中包括员工工号(8位)和年龄字段,以工号的最后一位来分表.同一时候,我们建立存储过程实

【转】Oracle - 数据库的实例、表空间、用户、表之间关系

[转]Oracle - 数据库的实例.表空间.用户.表之间关系 完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例. 1) 数据库是一系列物理文件的集合(数据文件,控制文件,联机日志,参数文件等): 2) Oracle数据库实例则是一组Oracle后台进程/线程以及在服务器分配的共享内存区. 在启动Oracle数据库服务器时,实际上是在服务器的内存中创建一个Oracle实例(即在服务器内存中分配共享内存并创建相关的后台内存),然后由这个Oracle数据库实例来访问和控制磁盘

通用超级强大的基于Oracle数据库的代码生成器

项目中使用了Oracle数据库,命名基本规范为表名和字段名全部大写,用下划线分割各个单词: 如“BASE_USER_LOGON_EXTEND”这个表表示用户登录的扩展表. 基于这个规范,通用权限管理系统配套升级了代码生成器工具. 下面以Oracle数据库中的BASE_USER_LOGON_EXTEND表来使用这个工具进行实体类和业务类代码的生成.  表结构图 代码生成器截图  实体层代码 1 //--------------------------------------------------

Oracle - 数据库的实例、表空间、用户、表之间关系

完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例. 1) 数据库是一系列物理文件的集合(数据文件,控制文件,联机日志,参数文件等): 2) Oracle数据库实例则是一组Oracle后台进程/线程以及在服务器分配的共享内存区. 在启动Oracle数据库服务器时,实际上是在服务器的内存中创建一个Oracle实例(即在服务器内存中分配共享内存并创建相关的后台内存),然后由这个Oracle数据库实例来访问和控制磁盘中的数据文件.Oracle有一个很大的内存快,成为全局区(SGA

ORACLE 数据库、实例、表空间、用户、数据库对象

Oracle是一种数据库管理系统,是一种关系型的数据库管理系统.通常情况了我们称的"数据库",包含了物理数据.数据库管理系统.内存.操作系统进程的组合体,就是指这里所说的数据库管理系统. 完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例. ① Oracle数据库是一系列物理文件的集合: 组成Oracle数据库的文件可以分成三个类型:数据文件(data file).重做日志文件(redo log file)和控制文件(control file).数据文件保存数据,

数据库关联映射建表图示(一对多、多对多)

~总结一下数据库的 一对多.多对一.一对一.多对多 关系 以及对应的建表方式~ 关联映射:一对多/多对一 存在最普遍的映射关系,简单来讲就如球员与球队的关系: 一对多:从球队角度来说一个球队拥有多个球员 即为一对多 多对一:从球员角度来说多个球员属于一个球队 即为多对一 数据表间一对多关系如下图: 关联映射:一对一 一对一关系就如球队与球队所在地址之间的关系,一支球队仅有一个地址,而一个地址区也仅有一支球队. 数据表间一对一关系的表现有两种,一种是外键关联,一种是主键关联.图示如下: 一对一外键

Oracle拉出在sqlserver建表的语句

我们将Oracle数据同步到sqlserver时,是先得在sqlserver端建表的. 复杂的字段我们不同步,就只考虑下面四种数据类型. Oracle到SQLServer做的映射: int -> int number -> decimal(18,6) number(p,s) -> decimal(p,s) date -> datetime varchar2(n) -> nvarchar(n) 下面是从Oracle端执行的plsql脚本. /* 简介:从oracle拉出在mss

Unity3D 连接MySQL数据库笔记3-SQL建表

打开  Navicat MySQL管理工具 连接到数据库 选择 test 数据库 点击 查询 输入对应的 sql命令 create table tuser( uname varchar(20) not null primary key, upwd varchar(20) not null ); create table p_info( pkey varchar(15) not null primary key, pname varchar(20) not null, psex varchar(2