SQL错误:ORA-01422:“精确提取返回的行数超过请求的行数”

SQL错误:ORA-01422:“精确提取返回的行数超过请求的行数”,sql,oracle,plsql,Sql,Oracle,Plsql,我很难理解我的SQL脚本出了什么问题。 我收到以下错误消息: 费勒贝里希特- ORA-01422:Exakter Abruf gibt mehr als die angeforderte Zeilenzahl zurück ORA-06512:在Zeile 58 00000-精确提取返回的行数超过请求的行数 *原因:精确提取中指定的行数小于返回的行数 *操作:重写查询或更改请求的行数 剧本: DECLARE obj_exists NUMBER (38, 0);

我很难理解我的SQL脚本出了什么问题。 我收到以下错误消息:

费勒贝里希特- ORA-01422:Exakter Abruf gibt mehr als die angeforderte Zeilenzahl zurück

ORA-06512:在Zeile 58

00000-精确提取返回的行数超过请求的行数 *原因:精确提取中指定的行数小于返回的行数

*操作:重写查询或更改请求的行数

剧本:

DECLARE
    obj_exists           NUMBER (38, 0);
    faqqestion           VARCHAR2 (4000 BYTE);
    targetobjid          NUMBER (38, 0);
    translatedtemplate   BOOLEAN;
BEGIN                                                         -- prints header
    DBMS_OUTPUT.Put_line (
           '"'
        || 'TemplateID'
        || '";"'
        || 'Templatetext'
        || '";"'
        || 'Sprache'
        || '";');

    -- iterates over the latest version of all 'de' templates
    FOR latestgermanobjects
        IN (  SELECT vs.sl_vs_id       vsId,
                     vs.sl_obj_id      vsObjId,
                     TRANSM.sl_obj_id  transmObjId,
                     TRANSM.lang,
                     OBJ.sl_obj_id     objObjId,
                     faq.faq_template_id faqTemplateId
                FROM sl_versionset vs
                     INNER JOIN sl_pp01_trans_meta transM
                         ON VS.sl_obj_id = TRANSM.sl_obj_id
                     INNER JOIN sl_pp01_obj obj
                         ON TRANSM.sl_obj_id = OBJ.sl_obj_id
                     INNER JOIN sl_pp01_faq01 faq
                         ON OBJ.sl_obj_id = FAQ.sl_obj_id
               WHERE     VS.sl_vs_next IS NULL
                     AND VS.sl_vs_deleted_flag = 0
                     AND VS.sl_vs_state <> 'Deprecated'
                     AND transm.lang = 'de'
                     AND obj.sl_obj_objtyp_id IN (334)
                     AND obj.sl_obj_deleted_flag = 0
            ORDER BY faq.faq_template_id ASC)
    LOOP
        -- iterate over all languages except 'de' to check translation
        FOR singlelanguagecursor
            IN (SELECT sl_metaval_varchar
                  FROM slma_meta_values
                 WHERE sl_metaval_varchar <> 'de' AND slma_metatype_id = 5)
        LOOP
            translatedtemplate := FALSE;

            -- iterate over all versions of versionset of the german template to find old tranlsations
            FOR templates
                IN (  SELECT sl_obj_id
                        FROM sl_versionset
                       WHERE     sl_vs_id = latestgermanobjects.vsid
                             AND sl_vs_deleted_flag = 0
                    ORDER BY sl_obj_id DESC)
            LOOP
                SELECT COUNT (1)
                  INTO obj_exists
                  FROM sl_pp01_trans_meta
                 WHERE     source_io = templates.sl_obj_id
                       AND lang = singlelanguagecursor.sl_metaval_varchar;

                -- checks, if a translation of the chosen language exists
                IF obj_exists >= 1
                THEN
                    translatedtemplate := TRUE;

                    -- if only a tranlsation of a older version of the source object exists
                    IF templates.sl_obj_id <> latestgermanobjects.objobjid
                    THEN
                        SELECT sl_obj_id
                          INTO targetobjid
                          FROM sl_pp01_trans_meta
                         WHERE     source_io = templates.sl_obj_id
                               AND lang =
                                       singlelanguagecursor.sl_metaval_varchar;

                        SELECT faq_question
                          INTO faqqestion
                          FROM sl_pp01_templ01
                         WHERE sl_obj_id = targetobjid;

                        -- prints 'Template Id', tranlsation of templatetext, language of translation of a transation of a older source object
                        DBMS_OUTPUT.Put_line (
                               '"'
                            || latestgermanobjects.faqtemplateid
                            || '";"'
                            || faqqestion
                            || '";"'
                            || singlelanguagecursor.sl_metaval_varchar
                            || '";');
                    END IF;

                    -- ends loop, after translation has found
                    EXIT;
                END IF;
            END LOOP;

            -- if no translation is available
            IF NOT translatedtemplate
            THEN
                DBMS_OUTPUT.Put_line (
                       '"'
                    || latestgermanobjects.faqtemplateid
                    || '";"'
                    || 'translation n/a'
                    || '";"'
                    || singlelanguagecursor.sl_metaval_varchar
                    || '";');
            END IF;
        END LOOP;
    END LOOP;
END;

SQL和PL/SQL新手,非常感谢您的帮助。

这里有一些示例解释您的错误代码:

declare
    v_text   VARCHAR2(4000);
begin

    -- this will work fine..
    SELECT * INTO v_text FROM
    ( -- this is a fake-table
        SELECT 'some text' FROM DUAL
    );

    dbms_output.put_line(v_text); 

    -- this will get you an no data found exception
    BEGIN

        SELECT * INTO v_text FROM
        ( -- this is a fake-table
            SELECT 'some text' FROM DUAL
        )
        WHERE 1 = 2;

        dbms_output.put_line(v_text);
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
        dbms_output.put_line('there is no data..');
    END;

    -- this will get you your exception 'too many rows'
    BEGIN

        SELECT * INTO v_text FROM
        ( -- this is a fake-table
            SELECT 'some text' FROM DUAL UNION ALL
            SELECT 'some text' FROM DUAL
        );

        dbms_output.put_line(v_text);
    EXCEPTION
        WHEN TOO_MANY_ROWS THEN
        dbms_output.put_line('there is too much data..');
    END;

end;
您的具体问题是第69行,我想:

SELECT sl_obj_id
  INTO targetobjid
  FROM sl_pp01_trans_meta
 WHERE     source_io = templates.sl_obj_id
       AND lang =
               singlelanguagecursor.sl_metaval_varchar;

如果您获得多行,则不允许您的输入。修复您的选择,其中ROWNUM=1!!!仅在结果正确时使用!!!或者处理异常。

您的SQL从sl_pp01_trans_meta选择sl_obj_id到targetobjid,其中source_io=templates.sl_obj_id和lang=singlelanguagecursor.sl_metaval\u varchar;返回多行。由于INTO子句,它应该只返回一行。顺便说一下,如果没有结果,选择xxx INTO vvv将返回一个错误。您应该在游标内进行这些查询并使用它们。你们的代码也会更可读。谢谢你们!