一個根據已有表結構來建立新表的儲存過程
最近開發人員頻繁要求參照舊錶結構來建立新表,每次人工操作比較繁瑣,寫了一個儲存過程來自動執行,如下:
create or replace procedure p_auto_create_tab(i_old_tab_name varchar2,i_new_tab_name varchar2)
as
--作者:
--建立時間:20170320
--適用資料庫版本:oracle 11g及以上版本
--功能:輸入已有表的表名和新建表的表名,自動建立新表及索引、序列,目前只支援非分割槽表和按天的範圍分割槽表,對於分割槽表,建立的是按天自動分割槽。
--輸入引數:i_old_tab_name 舊錶名,i_new_tab_name 新表名
v_ddl_sql VARCHAR2(32000);
v_tab_ddl CLOB;
v_ind_ddl CLOB;
v_create_sql CLOB;
v_create_ind_sql CLOB;
v_str_loc number;
v_part_key varchar2(30);
v_old_primary_key varchar2(30);
v_new_primary_key varchar2(30);
v_part_flag varchar2(30);
v_today date := sysdate;
v_index_name varchar2(30);
v_create_seq_sql varchar2(32000);
BEGIN
--獲取建表語句
dbms_metadata.set_transform_param(dbms_metadata.SESSION_TRANSFORM, 'SQLTERMINATOR', false);
v_ddl_sql := 'select dbms_metadata.get_ddl(''TABLE'','''||i_old_tab_name||''') from dual';
EXECUTE IMMEDIATE v_ddl_sql INTO v_tab_ddl;
--確認是否是分割槽表
select partitioned into v_part_flag from user_tables where table_name=i_old_tab_name;
--將建表語句中表名替換為新的表名
v_tab_ddl := dbms_lob.SUBSTR(v_tab_ddl,32767);
v_create_sql := replace(v_tab_ddl,i_old_tab_name,i_new_tab_name);
--獲取並修改主鍵名稱
BEGIN
--獲取主鍵名稱
select CONSTRAINT_NAME into v_old_primary_key from user_constraints where table_name=i_old_tab_name and CONSTRAINT_TYPE='P';
--生成新的主鍵名稱
v_new_primary_key := substr('PK_'||i_new_tab_name,0,30);
--替換主鍵名稱
v_create_sql := replace(v_create_sql,v_old_primary_key,v_new_primary_key);
exception when no_data_found then
NULL;
END;
--如果是分割槽表,加上建立分割槽的資訊
if (v_part_flag = 'YES') then
--獲取分割槽鍵
select column_name into v_part_key from user_part_key_columns where name=i_old_tab_name;
--去掉partition by後面的內容
v_str_loc := instr(v_create_sql,'PARTITION BY');
v_create_sql := substr(v_create_sql,0,v_str_loc-1);
--新增分割槽資訊
v_create_sql := v_create_sql||'partition by range ('||v_part_key||') interval(NUMTODSINTERVAL(1,''DAY''))(partition p'||to_char(v_today,'yyyymmdd')||' values less than(to_date('''||to_char(v_today,'yyyy-mm-dd')||''', ''yyyy-mm-dd'')))';
--else
--v_create_sql := substr(v_create_sql,1,length(v_create_sql)-1);
end if;
dbms_output.put_line(v_create_sql);
--建立表
execute immediate v_create_sql;
--開始建立索引
for item in (select index_name from user_indexes
where
index_name not in
(select index_name from user_constraints
where
table_name=i_old_tab_name and CONSTRAINT_TYPE='P')
and table_name=i_old_tab_name
)
loop
v_ddl_sql := 'select dbms_metadata.get_ddl(''INDEX'','''||item.index_name||''') from dual';
EXECUTE IMMEDIATE v_ddl_sql INTO v_ind_ddl;
--生成新的索引名稱
v_index_name := 'IDX_'||substr(i_new_tab_name,0,20)||'_'||to_char(trunc(dbms_random.value(100000,1000000)));
v_create_ind_sql := replace(v_ind_ddl,item.index_name,v_index_name);
v_create_ind_sql := replace(v_create_ind_sql,i_old_tab_name,i_new_tab_name);
--v_create_ind_sql := substr(v_create_ind_sql,1,length(v_create_ind_sql)-1);
dbms_output.put_line(v_create_ind_sql);
execute immediate v_create_ind_sql;
end loop;
--開始建立序列
v_create_seq_sql := 'create sequence seq_'||i_new_tab_name||' start with 1';
dbms_output.put_Line(v_create_seq_sql);
execute immediate v_create_seq_sql;
END;
/
---測試
set serveroutput on
exec p_auto_create_tab('GW_95555_RLOG','GW_12345_RLOG');
exec p_auto_create_tab('TT3','T333');
create or replace procedure p_auto_create_tab(i_old_tab_name varchar2,i_new_tab_name varchar2)
as
--作者:
--建立時間:20170320
--適用資料庫版本:oracle 11g及以上版本
--功能:輸入已有表的表名和新建表的表名,自動建立新表及索引、序列,目前只支援非分割槽表和按天的範圍分割槽表,對於分割槽表,建立的是按天自動分割槽。
--輸入引數:i_old_tab_name 舊錶名,i_new_tab_name 新表名
v_ddl_sql VARCHAR2(32000);
v_tab_ddl CLOB;
v_ind_ddl CLOB;
v_create_sql CLOB;
v_create_ind_sql CLOB;
v_str_loc number;
v_part_key varchar2(30);
v_old_primary_key varchar2(30);
v_new_primary_key varchar2(30);
v_part_flag varchar2(30);
v_today date := sysdate;
v_index_name varchar2(30);
v_create_seq_sql varchar2(32000);
BEGIN
--獲取建表語句
dbms_metadata.set_transform_param(dbms_metadata.SESSION_TRANSFORM, 'SQLTERMINATOR', false);
v_ddl_sql := 'select dbms_metadata.get_ddl(''TABLE'','''||i_old_tab_name||''') from dual';
EXECUTE IMMEDIATE v_ddl_sql INTO v_tab_ddl;
--確認是否是分割槽表
select partitioned into v_part_flag from user_tables where table_name=i_old_tab_name;
--將建表語句中表名替換為新的表名
v_tab_ddl := dbms_lob.SUBSTR(v_tab_ddl,32767);
v_create_sql := replace(v_tab_ddl,i_old_tab_name,i_new_tab_name);
--獲取並修改主鍵名稱
BEGIN
--獲取主鍵名稱
select CONSTRAINT_NAME into v_old_primary_key from user_constraints where table_name=i_old_tab_name and CONSTRAINT_TYPE='P';
--生成新的主鍵名稱
v_new_primary_key := substr('PK_'||i_new_tab_name,0,30);
--替換主鍵名稱
v_create_sql := replace(v_create_sql,v_old_primary_key,v_new_primary_key);
exception when no_data_found then
NULL;
END;
--如果是分割槽表,加上建立分割槽的資訊
if (v_part_flag = 'YES') then
--獲取分割槽鍵
select column_name into v_part_key from user_part_key_columns where name=i_old_tab_name;
--去掉partition by後面的內容
v_str_loc := instr(v_create_sql,'PARTITION BY');
v_create_sql := substr(v_create_sql,0,v_str_loc-1);
--新增分割槽資訊
v_create_sql := v_create_sql||'partition by range ('||v_part_key||') interval(NUMTODSINTERVAL(1,''DAY''))(partition p'||to_char(v_today,'yyyymmdd')||' values less than(to_date('''||to_char(v_today,'yyyy-mm-dd')||''', ''yyyy-mm-dd'')))';
--else
--v_create_sql := substr(v_create_sql,1,length(v_create_sql)-1);
end if;
dbms_output.put_line(v_create_sql);
--建立表
execute immediate v_create_sql;
--開始建立索引
for item in (select index_name from user_indexes
where
index_name not in
(select index_name from user_constraints
where
table_name=i_old_tab_name and CONSTRAINT_TYPE='P')
and table_name=i_old_tab_name
)
loop
v_ddl_sql := 'select dbms_metadata.get_ddl(''INDEX'','''||item.index_name||''') from dual';
EXECUTE IMMEDIATE v_ddl_sql INTO v_ind_ddl;
--生成新的索引名稱
v_index_name := 'IDX_'||substr(i_new_tab_name,0,20)||'_'||to_char(trunc(dbms_random.value(100000,1000000)));
v_create_ind_sql := replace(v_ind_ddl,item.index_name,v_index_name);
v_create_ind_sql := replace(v_create_ind_sql,i_old_tab_name,i_new_tab_name);
--v_create_ind_sql := substr(v_create_ind_sql,1,length(v_create_ind_sql)-1);
dbms_output.put_line(v_create_ind_sql);
execute immediate v_create_ind_sql;
end loop;
--開始建立序列
v_create_seq_sql := 'create sequence seq_'||i_new_tab_name||' start with 1';
dbms_output.put_Line(v_create_seq_sql);
execute immediate v_create_seq_sql;
END;
/
---測試
set serveroutput on
exec p_auto_create_tab('GW_95555_RLOG','GW_12345_RLOG');
exec p_auto_create_tab('TT3','T333');
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10972173/viewspace-2137769/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- csii_根據acct表同一個acctnbr(列轉行)動態sql_儲存過程SQL儲存過程
- mysql 儲存過程 procedure 批次建表MySql儲存過程
- PostgreSQL獲取建表語句儲存過程SQL儲存過程
- 根據結構基本相同的A表的值更新B表
- java儲存過程根據檔案的內容返回一個MD5值Java儲存過程
- 如何把SQL Server中一個表,一個儲存過程,一個檢視等改為系統表,系統儲存過程,系統檢視等...SQLServer儲存過程
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- Sql儲存過程分頁--臨時表儲存SQL儲存過程
- 更新大表中某個欄位的儲存過程儲存過程
- EF:根據實體類生成表結構SQLSQL
- 用儲存過程動態建立表儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- MySql儲存過程—2、第一個MySql儲存過程的建立MySql儲存過程
- 把一個資料表中的資料匯入另一個表,觸發器和儲存過程的觸發器儲存過程
- innodb表空間儲存結構
- 向已有的excel表中追加資料儲存(表頭一致)Excel
- db2刪除已經儲存的表儲存過程DB2儲存過程
- 根據表結構,自動生成匯入指令碼指令碼
- 儲存過程獲取表被引用的資訊儲存過程
- 利用mysqldump只匯出資料庫的表結構、儲存過程和函式MySql資料庫儲存過程函式
- bbs的資料結構和儲存過程(一) (轉)資料結構儲存過程
- Django2.0-db(12)-根據已有的表自動生成模型Django模型
- MySQL 儲存過程進行切換表MySql儲存過程
- 一個儲存過程的問題!儲存過程
- MySQL的物理儲存結構和session過程MySqlSession
- 在儲存過程中建立表的兩種方法儲存過程
- 在儲存過程A中呼叫儲存過程B的結果儲存過程
- laravel建立一個儲存過程Laravel儲存過程
- 用自訂函式實現功能-------根據指定表名得到表的結構 (轉)函式
- 遷移表結構時儲存空間過大問題
- Mysql 資料庫水平分表 儲存過程MySql資料庫儲存過程
- 11 線性表的順序儲存結構
- mysql返回一個結果集的儲存過程小例子MySql儲存過程
- Mysql-Innodb : 從一個位元組到整個資料庫表瞭解物理儲存結構和邏輯儲存結構MySql資料庫
- 線性表之順序儲存結構
- 線性表之鏈式儲存結構
- 查詢多張表記錄數的儲存過程儲存過程
- sql server 儲存過程中使用變數表,臨時表的分析(續)SQLServer儲存過程變數