You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 11:19:36