Oracle使用PL/SQL脚本给表结构相同的动态表添加字段

来源:互联网 发布:mac上海店 编辑:程序博客网 时间:2024/06/06 12:27

背景

数据库中有400多个表结构相同的动态表, 这些表只有表名称稍微不一样, 现在需要给每个表添加一个相同的字段newField。 手工为每个表添加不太现实, 于是通过SQL脚本来实现是比较快捷的方法。 
以后涉及到动态表更新字段,删除字段都可以参考这个实现,稍微修改下,就可以了。

思路

思路超简单啦,
1.查询出所有需要添加字段的动态表
2.循环遍历这些动态表
3.检查数据表是否已经存在该字段,若不存在,添加字段

示例

第一次使用PL/SQL语法, 感觉和MS SQL Server的t-sql语法差别挺大的。
关键语法:for循环, if/else条件判断的使用
[sql] view plaincopy
  1. /**  
  2.  *  
  3.  * Function:动态表添加字段newField  
  4.  * author: codemouse  
  5.  * date: Jun.5th, 2012  
  6.  *    
  7.  */  
  8.  /**  
  9.    
  10.  代码逻辑:   
  11.          1.所有动态表的表名以prefix_作为前缀, 后面接递增的后缀字符串(如00001,00002, ..), 再接分钟值(如1,60,1440) ,备份数据表以_bak结尾  
  12.          如:prefix_00001,prefix_00001_bak, prefix_00001_1, prefix_00001_1_bak, prefix_00001_60, prefix_00001_60_bak, ...  
  13.              prefix_00002, prefix_00002_bak, prefix_00002_1, prefix_00002_1_bak, prefix_00002_60, prefix_00002_60_bak, ..  
  14.              prefix_00003, ....  
  15.              ... ...  
  16.          2.递增的后缀字符串存放在table_mt表中的counter字段中(如: 00001, 00002, 00003, ...)  
  17.          3.前缀prefix_和后缀字符串拼接在一起就是一个动态表名的前缀了, 所以先要遍历table_mt, 得到动态表的名称的前缀, 如prefix_00001,prefix_00002, ...  
  18.          4.在当前用户下查找到符合前缀的表:如前缀为prefix_00001的表:prefix_00001,prefix_00001prefix_00001_bak, prefix_00001_1   
  19.          5.判断字段是否存在  
  20.          6.不存在则添加  
  21.  **/  
  22. declare   
  23.         --动态表表名前缀  
  24.         tbl_name_prefix nvarchar2(255);  
  25.         --表名  
  26.         tbl_name nvarchar2(255);  
  27.         --字段  
  28.         add_column_name nvarchar2(255):='newField';  
  29.         --存放sql语句的字符串  
  30.         sql_str nvarchar2(500);  
  31.         --字段是否已存在  
  32.         is_exist number:=0;  
  33.           
  34.         c_name number;  
  35.         ret number;  
  36.         --记录动态表的的数量  
  37.         mt_counter number:=0;  
  38.           
  39. begin  
  40.         --for循环  
  41.         for counter_record in (select counter from table_mt where nodetype = 'water' order by counter) loop  
  42.             begin   
  43.                        tbl_name_prefix := 'prefix_'||counter_record.counter;  
  44.                        --dbms_output.put_line('tbl_name_prefix: '|| tbl_name_prefix);  
  45.                        mt_counter := mt_counter + 1;  
  46.                        for tbl_name_record in (select table_name from USER_TABLES where table_name like tbl_name_prefix||'%') loop  
  47.                            dbms_output.put_line('tbl_name: '|| tbl_name_record.table_name);  
  48.                              
  49.                            select count(column_name) into is_exist   
  50.                            from cols  
  51.                            where table_name = upper(tbl_name_record.table_name)   
  52.                            and column_name = upper(add_column_name);  
  53.                              
  54.                            if(is_exist = 0) then  
  55.                                   dbms_output.put_line('字段 ['||add_column_name||'] 在表'||tbl_name_record.table_name||'中不存在');  
  56.                                   sql_str:= 'alter table '|| tbl_name_record.table_name|| ' add ' || add_column_name || ' float null';  
  57.                                   dbms_output.put_line('添加列, 动态执行DDL语句: '||sql_str);  
  58.                                     
  59.                                   ---动态执行DDL语句  
  60.                                   --execute immediate sql_str;  
  61.                                   c_name:=dbms_sql.open_cursor;  
  62.                                   dbms_sql.parse(c_name, sql_str, dbms_sql.native);  
  63.                                   ret:= dbms_sql.execute(c_name);  
  64.                                   dbms_sql.close_cursor(c_name);  
  65.                                     
  66.                            else  
  67.                                   dbms_output.put_line('字段 ['||add_column_name||'] 已经存在于表'||tbl_name_record.table_name||'中');  
  68.                            end if;  
  69.                        end loop;  
  70.             end;  
  71.         end loop;  
  72.         dbms_output.put_line('共有: [' || mt_counter || '] 个动态表。');  
  73. end
0 0