Oracle DB - 创建表为 - 导致“ORA-01489:字符串连接的结果太长”

问题描述 投票:0回答:1

我在存储过程中发现了一种奇怪的行为,该存储过程在将标准化报告历史记录到我们的 Oracle 数据库中时在 99% 的情况下都能正常工作。

对于某些报告,我收到错误 ORA-01489:字符串连接的结果太长。该过程创建一个包含所有数据的临时表,并添加复合主哈希键和哈希业务键。

如果我只执行

SELECT
声明而不执行
CREATE TABLE temp_tbl
对于导致麻烦的报告,它就可以正常工作。
CREATE TABLE ... AS
功能是否有任何已知限制?

sql_cmd varchar2(32767);

BEGIN
sql_cmd:= 'CREATE TABLE temp_tbl AS (
        SELECT 
            ID_00010, ID_00020, ID_00030, ID_00040,  to_timestamp(ID_00050, 'YYYY-MM-DD hh24:mi:ss') as ID_00050, ID_00060, [...],
            to_timestamp("PARSER_TIMESTAMP", 'YYYY-MM-DD hh24:mi:ss') as "PARSER_TIMESTAMP",
            
            CAST(STANDARD_HASH(
            STANDARD_HASH(
         UTL_RAW.CAST_TO_RAW(ID_00010|| ID_00020|| ID_00030|| ID_00040|| ID_00050|| [...])
       || UTL_RAW.CAST_TO_RAW(ID_11040|| ID_12000|| ID_13000|| ID_20000|| [...])
       , 'SHA1')
        ||
     STANDARD_HASH(UTL_RAW.CAST_TO_RAW(ID_20160|| ID_20170|| ID_20180|| ID_20190|| ID_20200|| [...])
       || UTL_RAW.CAST_TO_RAW(ID_20680|| ID_20690|| ID_20700|| ID_20710||  [...])
        , 'SHA1')
        ||   
    STANDARD_HASH(UTL_RAW.CAST_TO_RAW(ID_30780|| ID_30790|| ID_30800|| [...])
       || UTL_RAW.CAST_TO_RAW(ID_30980|| ID_30990|| [...])
       || UTL_RAW.CAST_TO_RAW(ID_31820|| ID_31830|| [...])
       || UTL_RAW.CAST_TO_RAW(ID_32680|| ID_32690|| [...])
       || UTL_RAW.CAST_TO_RAW(ID_50710|| ID_50720|| [...])
    , 'SHA1')
    , 'SHA1') as CHAR(160)) as PK_HASH_KEY,
                CAST(STANDARD_HASH(utl_raw.cast_to_raw(id_20000), 'SHA1') as CHAR(160)) as BK_HASH_KEY
            FROM stg_tbl
            )'

EXECUTE IMMEDIATE sql_cmd;
END;

附加信息

  • cmd_sql
    字符串的长度为13969,不应成为问题的原因,因为它是静态文本并且适用于相同类型的其他报告。

  • 由于 4000 个字符的串联限制,我将 PK_HASH_KEY 生成拆分为多个“子哈希键”。导致上述错误的报告的子哈希键远低于限制:

Char Length of the sub hash keys

  • 错误信息

错误报告-ORA-01489:字符串连接结果太长 ORA-06512: 在“DATAENGINEER.LOAD_PROC”,第 38 行 ORA-06512: 在 2号线 01489. 00000 - “字符串连接的结果太长” *原因:字符串拼接结果超过最大长度。 *操作:确保结果小于最大尺寸。

  • Oracle Database 19c 企业版版本 19.0.0.0.0 - 生产
oracle stored-procedures string-concatenation create-table oracle19c
1个回答
0
投票

将问题分成更小的问题并解决更小的问题。

您有疑问:

CREATE TABLE ... AS SELECT ...

错误可能出现在

SELECT ...
中,因此请尝试运行
SELECT
语句,而不是在 PL/SQL 中并且不创建表:

SELECT ID_00010,
       ID_00020,
       ID_00030,
       ID_00040,
       to_timestamp(ID_00050, 'YYYY-MM-DD hh24:mi:ss') as ID_00050,
       ID_00060,
       -- ...,
       to_timestamp("PARSER_TIMESTAMP", 'YYYY-MM-DD hh24:mi:ss') as "PARSER_TIMESTAMP"
FROM   stg_tbl

如果运行(应该),那么问题出在散列中,因此运行用于第一个散列的串联:

SELECT UTL_RAW.CAST_TO_RAW(
         ID_00010
         || ID_00020
         || ID_00030
         || ID_00040
         || ID_00050
         -- || ...
       )
FROM   stg_tbl

重复代码的下一部分,直到找到有问题的代码部分。

© www.soinside.com 2019 - 2024. All rights reserved.