PROCEDURE Etl_ADDR IS
V_CNT_AG NUMBER(10);
BEGIN
INSERT INTO 日志表1;
COMMIT; EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM 地址表1 WHERE ROWNUM<10' INTO V_CNT_AG;
IF V_CNT_AG>0 THEN
--备份
EXECUTE IMMEDIATE 'TRUNCATE TABLE 地址备份表1';
INSERT INTO 地址备份表1 SELECT * FROM 地址表1;
COMMIT;
--导入
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 DROP CONSTRAINT 主键1';
EXCEPTION
WHEN OTHERS THEN
NULL;
END; EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 TRUNCATE 分区.. '; BEGIN
EXECUTE IMMEDIATE '
INSERT INTO 地址表1(ID, NAME, GRADE, PARENTID, ADDR)
SELECT AG.ID, AG.NAME, NVL(AG.GRADE,-1), AG.PARENTID, AG.ADDR
FROM 源地址表';
COMMIT;
DBMS_STATS.gather_table_stats(……);
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 ADD CONSTRAINT 主键1
USING INDEX TABLESPACE "INDEX" NOLOGGING';
DBMS_STATS.gather_index_stats(……);
EXCEPTION
WHEN OTHERS THEN
NULL;
END; EXCEPTION
WHEN OTHERS THEN
--恢复
V_ERROR_MESSAGE := 'OTHER ERROR: '||substr(sqlerrm(SQLCODE),1,255);
INSERT INTO 日志表1;
EXECUTE IMMEDIATE 'TRUNCATE TABLE 地址表1';
INSERT INTO 地址表1 SELECT * FROM 地址备份表1;
COMMIT;
DBMS_STATS.gather_table_stats(……); BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 ADD CONSTRAINT 主键1
USING INDEX TABLESPACE "INDEX" NOLOGGING';
DBMS_STATS.gather_index_stats(……);
EXCEPTION
WHEN OTHERS THEN
NULL;
END; END;
END IF; INSERT INTO 日志表1;
COMMIT;
Exception WHEN OTHERS THEN
V_ERROR_MESSAGE := 'OTHER ERROR: '||substr(sqlerrm(SQLCODE),1,255);
INSERT INTO 日志表1;
COMMIT;
END Etl_ADDR;
------------------------------------
提问:execute immediate 不是用来执行动态sql语句的吗,但是上面那个例子怎么用它来执行查询(select)、删除表的内容(truncate)、增加主键(alter)和插入数据(insert)
而同样的,存过里不也有单独的insert into语句(没有放在execute immediate里)吗,那针对上面标示为橙色的四个execute immediate的意义大家能解释一下吗?实在搞糊涂了
V_CNT_AG NUMBER(10);
BEGIN
INSERT INTO 日志表1;
COMMIT; EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM 地址表1 WHERE ROWNUM<10' INTO V_CNT_AG;
IF V_CNT_AG>0 THEN
--备份
EXECUTE IMMEDIATE 'TRUNCATE TABLE 地址备份表1';
INSERT INTO 地址备份表1 SELECT * FROM 地址表1;
COMMIT;
--导入
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 DROP CONSTRAINT 主键1';
EXCEPTION
WHEN OTHERS THEN
NULL;
END; EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 TRUNCATE 分区.. '; BEGIN
EXECUTE IMMEDIATE '
INSERT INTO 地址表1(ID, NAME, GRADE, PARENTID, ADDR)
SELECT AG.ID, AG.NAME, NVL(AG.GRADE,-1), AG.PARENTID, AG.ADDR
FROM 源地址表';
COMMIT;
DBMS_STATS.gather_table_stats(……);
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 ADD CONSTRAINT 主键1
USING INDEX TABLESPACE "INDEX" NOLOGGING';
DBMS_STATS.gather_index_stats(……);
EXCEPTION
WHEN OTHERS THEN
NULL;
END; EXCEPTION
WHEN OTHERS THEN
--恢复
V_ERROR_MESSAGE := 'OTHER ERROR: '||substr(sqlerrm(SQLCODE),1,255);
INSERT INTO 日志表1;
EXECUTE IMMEDIATE 'TRUNCATE TABLE 地址表1';
INSERT INTO 地址表1 SELECT * FROM 地址备份表1;
COMMIT;
DBMS_STATS.gather_table_stats(……); BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 ADD CONSTRAINT 主键1
USING INDEX TABLESPACE "INDEX" NOLOGGING';
DBMS_STATS.gather_index_stats(……);
EXCEPTION
WHEN OTHERS THEN
NULL;
END; END;
END IF; INSERT INTO 日志表1;
COMMIT;
Exception WHEN OTHERS THEN
V_ERROR_MESSAGE := 'OTHER ERROR: '||substr(sqlerrm(SQLCODE),1,255);
INSERT INTO 日志表1;
COMMIT;
END Etl_ADDR;
------------------------------------
提问:execute immediate 不是用来执行动态sql语句的吗,但是上面那个例子怎么用它来执行查询(select)、删除表的内容(truncate)、增加主键(alter)和插入数据(insert)
而同样的,存过里不也有单独的insert into语句(没有放在execute immediate里)吗,那针对上面标示为橙色的四个execute immediate的意义大家能解释一下吗?实在搞糊涂了
而同样的,存过里不也有单独的insert into语句(没有放在execute immediate里)吗,那针对上面标示为橙色的四个execute immediate的意义大家能解释一下吗?实在搞糊涂了这就是execute immediate动态的执行 select 、truncate、alter、insert 语句而已。
4. EXECUTE IMMEDIATE '
INSERT INTO 地址表1(ID, NAME, GRADE, PARENTID, ADDR)
SELECT AG.ID, AG.NAME, NVL(AG.GRADE,-1), AG.PARENTID, AG.ADDR
FROM 源地址表';这两个没有必要使用的,这完全是作者不好的编码习惯2. EXECUTE IMMEDIATE 'TRUNCATE TABLE 地址备份表1'
3. EXECUTE IMMEDIATE 'ALTER TABLE 地址表1 DROP CONSTRAINT 主键1';
存储过程里不能直接执行 truncate, alter 语句,所以只能使用动态语句来实现
如果表名是变量的话,不是固定的值,那么就有必要用EXECUTE IMMEDIATE了。
ALTER ...
CREATE ...
TRUNCATE 等。