哪种数据类型比CLOB支持更多的字符串/字符

时间:2018-08-09 08:59:25

标签: oracle plsql oracle11g

当前,我使用CLOB来存储all_objects存储过程的定义,但是过程长度很长,因此使用Excute Instant很难执行,因为它跨越了CLOB的长度,

  
    

ORA-06502:PL / SQL:数字或值错误     06502。00000-“ PL / SQL:数值或值错误%s”     *原因:算术,数字,字符串,转换或约束错误                发生。例如,如果尝试执行以下操作,则会发生此错误                将值NULL分配给声明为NOT NULL的变量,或者                尝试将大于99的整数分配给变量                声明为NUMBER(2)。     *操作:更改数据,如何操作或声明数据                值不违反约束条件。

  
DECLARE
    v_output   CLOB := NULL;
    a          CLOB := NULL;
    srce       VARCHAR2(1000) := NULL;
BEGIN
   -- Note,we don't search for package bodies. We will extract the body
   -- along with the package spec.
    dbms_output.put_line('Database DDL For Selected Objects Report');
    FOR dd IN (
        SELECT
            object_name,
            status
        FROM
            all_objects
        WHERE
                status != 'VALID'
            AND
                object_name LIKE '%SP_RPT%'
    ) LOOP
        a := '';
        srce := dd.object_name;
        dbms_output.put_line(srce || ' proceudure creation start');
        FOR dd1 IN (
            SELECT
                text
            FROM
                dba_source
            WHERE
                    type = 'PROCEDURE'
                AND
                    name LIKE dd.object_name
        ) LOOP
-- DBMS_OUTPUT.put_line (dd1.text);
            a := a || dd1.text;
     --       DBMS_OUTPUT.put_line (a);
        END LOOP;

        dbms_output.put_line(a);
   --  EXECUTE IMMEDIATE a ;
        dbms_output.put_line(srce || ' proceudure Updated successfully');
    END LOOP;

EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line('ERROR occured while creating Procedure ' || srce);
        dbms_output.put_line(a);
        dbms_output.put_line(substr(
            dbms_utility.format_error_stack
             || ' ,'
             || dbms_utility.format_error_backtrace,
            1,
            500
        ) );

        RAISE;
END;

2 个答案:

答案 0 :(得分:2)

execute_immediate_statement

dynamic_sql_stmt

表示SQL语句的字符串文字,字符串变量或字符串表达式。其类型必须是CHAR,VARCHAR2或CLOB。

参考:https://docs.oracle.com/database/121/LNPLS/executeimmediate_statement.htm#LNPLS01317

有关数据类型大小和用法的更多信息,请参见:https://sqljana.wordpress.com/2017/02/07/oracle-clob-vs-varchar2-when-when-not-to-use/

我建议您选择CLOB是更好的选择。

答案 1 :(得分:1)

您可以这样尝试:

FOR dd1 IN (SELECT text FROM dba_source WHERE ... ORDER BY LINE) LOOP
    a := a || dd1.text ||CHR(13);
END LOOP;

但是,这样做的目的是什么?很有可能是一个简单的

FOR dd IN (
    SELECT object_name, object_type, status
    FROM all_objects
    WHERE status != 'VALID'
        AND object_name LIKE '%SP_RPT%') 
LOOP
    EXECUTE IMMEDIATE 'ALTER '||dd.object_type||' '||dd.object_name||' COMPILE';
    if dd.object_type = 'PACKAGE BODY' THEN
       EXECUTE IMMEDIATE 'ALTER '||dd.object_type||' '||dd.object_name||' COMPILE BODY';
    END IF;
END LOOP;

会做同样的事情。