-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathGET_INSERT_SCRIPT_ORACLE.sql
More file actions
219 lines (177 loc) · 6.8 KB
/
GET_INSERT_SCRIPT_ORACLE.sql
File metadata and controls
219 lines (177 loc) · 6.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
create type linha_script is object (conteudo varchar2(4000));
/
create type tabela_linha is table of linha_script;
/
CREATE OR REPLACE FUNCTION GET_INSERT_SCRIPT (
V_TABLE_NAME VARCHAR2,
V_OWNER_ORIGEM VARCHAR2,
V_OWNER_DESTINO VARCHAR2)
RETURN tabela_linha
AS
tabela_existe BOOLEAN := FALSE;
-- variáveis auxiliares para execução e geração
id_cursor NUMBER;
col_count NUMBER;
descricao_tab dbms_sql.desc_tab;
TYPE cur_typ IS REF CURSOR;
cur cur_typ;
-- variáveis com valores parciais de uma linha
tmp_campos VARCHAR2(4000) := '';
nc int := 0;
tmp_valores VARCHAR2(4000) := '';
nv int := 0;
-- variáveis para recuperar valores dos campos
namevar VARCHAR2(32767);
numvar NUMBER;
datevar DATE;
query VARCHAR2(4000);
--n INT;
-- variáveis de tabelas para armazenar todas as linhas de dados
campos tabela_linha := tabela_linha();
valores tabela_linha := tabela_linha();
BEGIN
-- procura a tabela e abre um cursor implícito
FOR TAB_REC IN
(SELECT TABLE_NAME, OWNER
FROM ALL_TABLES
WHERE TABLE_NAME = UPPER(V_TABLE_NAME)
AND V_OWNER_ORIGEM = UPPER(OWNER)) LOOP
-- armazena que a tabela foi encontrada
tabela_existe := true;
-- executa a query para recuperar todos os valores, abrindo um cursor através da biblioteca do oracle
query := 'SELECT * FROM ' || TAB_REC.OWNER || '.' || TAB_REC.TABLE_NAME;
id_cursor := dbms_sql.open_cursor;
dbms_sql.parse(id_cursor, query, dbms_sql.native);
--recupera descrição das colunas do cursor
dbms_sql.describe_columns( c => id_cursor, col_cnt => col_count, desc_t => descricao_tab);
-- inicia variáveis parciais dos campos e dos valores
tmp_campos := ' (';
-- adiciona a primeira linha do INSERT
campos.extend;
nc := nc + 1;
campos(nc) := linha_script('INSERT INTO ' || V_OWNER_DESTINO || '.' || TAB_REC.TABLE_NAME);
-- percorre todas as colunas, cria a lista de campos do insert e faz o bind das colunas de retorno
FOR i IN 1 .. col_count LOOP
--somente coloca a vírgula a partir de segundo elemento
if i > 1 then
tmp_campos := tmp_campos || ', ';
--quebra linha a cada N elementos
if i mod 30 = 0 then
--adiciona a linha de elementos parcial na lista final
campos.extend;
nc := nc + 1;
campos(nc) := linha_script(tmp_campos);
--limpa a variável de campos parcial
tmp_campos := ' ';
end if;
end if;
--adiciona o campo atual na variável parciaç
tmp_campos := tmp_campos || descricao_tab(i).col_name;
--bind das colunas de resultado
IF descricao_tab(i).col_type = 2 THEN
DBMS_SQL.DEFINE_COLUMN(id_cursor, i, numvar);
ELSIF descricao_tab(i).col_type = 12 THEN
DBMS_SQL.DEFINE_COLUMN(id_cursor, i, datevar);
ELSE
DBMS_SQL.DEFINE_COLUMN(id_cursor, i, namevar, 4000);
END IF;
END LOOP;
--adiciona última linha de campos
campos.extend;
nc := nc + 1;
campos(nc) := linha_script(tmp_campos || ')');
--inicia parte dos calores
campos.extend;
nc := nc + 1;
campos(nc) := linha_script('VALUES');
--executa o select * na tabela
if dbms_sql.execute(id_cursor) = 0 then
--cabeçalho
valores.extend;
nv := nv + 1;
valores(nv) := linha_script('---------- CARGA DA TABELA ' || TAB_REC.OWNER || '.' || TAB_REC.TABLE_NAME || '----------');
--adiciona linha para DELETE
valores.extend;
nv := nv + 1;
valores(nv) := linha_script('DELETE FROM ' || V_OWNER_DESTINO || '.' || TAB_REC.TABLE_NAME || ';');
--percorre os registros retornados pelo select
while dbms_sql.fetch_rows(id_cursor) > 0 LOOP
--adiciona as linhas dos campos "INSERT INTO TAB (CAMPO1, CAMPO2, ...) VALUES " para cada conjunto de valores
FOR i IN 1 .. nc LOOP
valores.extend;
nv := nv + 1;
valores(nv) := campos(i);
END LOOP;
--inicia a lista de valores
tmp_valores := ' (';
--percorre cada coluna do registro atual
FOR i IN 1 .. col_count LOOP
--somente coloca a vírgula a partir de segundo elemento
if i > 1 then
tmp_valores := tmp_valores || ', ';
--quebra linha a cada N elementos
if i mod 30 = 0 then
--adiciona a linha de elementos parcial na lista final
valores.extend;
nv := nv + 1;
valores(nv) := linha_script(tmp_valores);
--limpa a variável de valores parcial
tmp_valores := ' ';
end if;
end if;
--recupera o valor dependendo do tipo e adiciona à variável parcial de valores
if descricao_tab(i).col_type = 2 then --number
DBMS_SQL.COLUMN_VALUE(id_cursor, i, numvar);
if numvar is null then
tmp_valores := tmp_valores || 'null';
else
tmp_valores := tmp_valores || replace(to_char(numvar),',','.');
end if;
elsif descricao_tab(i).col_type = 12 then --date
DBMS_SQL.COLUMN_VALUE(id_cursor, i, datevar);
if datevar is null then
tmp_valores := tmp_valores || 'null';
else
if datevar = trunc(datevar) then
tmp_valores := tmp_valores || 'to_date('''
|| to_char(datevar, 'DD/MM/YYYY') ||''',''DD/MM/YYYY'')';
else
tmp_valores := tmp_valores || 'to_date('''
|| to_char(datevar, 'DD/MM/YYYY hh24:mi:ss') ||''',''DD/MM/YYYY hh24:mi:ss'')';
end if;
end if;
else --varchar2, char, others
DBMS_SQL.COLUMN_VALUE(id_cursor, i, namevar);
if namevar is null then
tmp_valores := tmp_valores || 'null';
else
tmp_valores := tmp_valores || '''' || namevar || '''';
end if;
end if;
end loop;
--adiciona última linha de valores
valores.extend;
nv := nv + 1;
valores(nv) := linha_script(tmp_valores || ');');
END LOOP;
--adiciona um commit ao final de cada tabela (rodapé)
valores.extend;
nv := nv + 1;
valores(nv) := linha_script('commit;');
--adiciona uma linha em branco
valores.extend;
nv := nv + 1;
valores(nv) := linha_script('');
end if;
--fecha o cursor
dbms_sql.close_cursor(id_cursor);
END LOOP;
--se a tabela não existir, retorna um comentário de erro
IF NOT tabela_existe THEN
campos.extend;
campos(1) := linha_script('-- Table ' || V_TABLE_NAME || ' not found');
return campos;
END IF;
RETURN valores;
END;
/