PL/SQL代码创建表成功但无法插入数据的问题求助
PL/SQL代码创建表成功但无法插入数据的问题求助
回答:
兄弟,你这个问题十有八九是没提交事务搞的鬼!Oracle里DML操作(比如INSERT)默认是不会自动提交的,PL/SQL块执行完之后,这些插入操作还在事务里挂着,你不手动提交的话,会话结束后事务就回滚了,所以表看起来是空的。
先试试在你的PL/SQL块最后加一句COMMIT;,比如:
DECLARE table_or_view_does_not_exist exception; pragma exception_init(table_or_view_does_not_exist,-00942); d_table varchar2(200); q_table varchar2(200); v_sql VARCHAR2(4000); v_value VARCHAR2(4000); v_cur SYS_REFCURSOR; BEGIN DBMS_OUTPUT. ENABLE (buffer_size => NULL); begin d_table:='drop table fms_addr_Spcl_Char PURGE'; execute immediate d_table; exception when table_or_view_does_not_exist then null; end; q_table:='create table fms_addr_Spcl_Char (table_name varchar2(50), column_name varchar2(50), spcl_char varchar2(500), spcl_char_count varchar2(50))'; execute immediate q_table; FOR r IN ( select table_name, column_name from all_tab_columns where table_name=upper('fms_user_address_book') and OWNER = 'FMS_ADMIN' ) loop v_sql := 'select "'||r.column_name||'" AS data from "'||r.table_name||'" where regexp_like ("'||r.column_name||'",''[&]'') and zone=''SZ'''; -- DBMS_OUTPUT.PUT_LINE(v_sql); OPEN v_cur FOR v_sql; LOOP FETCH v_cur INTO v_value; EXIT WHEN v_cur%NOTFOUND; DBMS_OUTPUT.PUT_LINE(r.table_name || '.' || r.column_name || '---->' || v_value||' '||v_cur%rowcount); execute immediate 'insert into fms_addr_Spcl_Char values (:param1,:param2,:param3,:param4)' using r.table_name,r.column_name ,v_value,v_cur%rowcount; END LOOP; CLOSE v_cur; -- 新增:关闭游标避免泄漏 END LOOP; -- 新增:提交事务 COMMIT; END; /
另外我还发现几个可以优化的小细节,顺便给你提个醒:
- 游标必须关闭:你之前打开游标后没有显式关闭,长时间运行容易造成游标泄漏,已经在上面的代码里帮你加上了
CLOSE v_cur; - 类型转换更严谨:你插入的
v_cur%rowcount是数字类型,但目标表的spcl_char_count是varchar2(50),虽然Oracle会自动隐式转换,但最好显式写成TO_CHAR(v_cur%rowcount),避免特殊场景下出问题 - SQL拼接更安全:当前用字符串拼接生成查询SQL的方式,虽然从系统视图取的表/列名风险不高,但可以用
DBMS_ASSERT.ENQUOTE_NAME来包裹表名和列名,既安全又能处理大小写敏感的情况,比如:v_sql := 'select '||DBMS_ASSERT.ENQUOTE_NAME(r.column_name)||' AS data from '||DBMS_ASSERT.ENQUOTE_NAME(r.table_name)||' where regexp_like ('||DBMS_ASSERT.ENQUOTE_NAME(r.column_name)||',''[&]'') and zone=''SZ''';
先加COMMIT试试,应该就能看到数据了!如果还是不行,把DBMS_OUTPUT.PUT_LINE(v_sql);的注释打开,看看生成的查询语句能不能手动查到数据,或者在插入语句后加个输出,确认插入逻辑是不是真的执行了。
备注:内容来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

