Oracle 通过sql profile为sql语句加hint(3)

-- trim parameters
    COL sql_id NEW_V sql_id FOR A30;
    COL plan_hash_value NEW_V plan_hash_value FOR A30;
    SELECT TRIM('&&sql_id.') sql_id, TRIM('&&plan_hash_value.') plan_hash_value FROM DUAL;

VAR sql_text CLOB;
    VAR other_xml CLOB;
    EXEC :sql_text := NULL;
    EXEC :other_xml := NULL;

-- get sql_text from memory
    DECLARE
      l_sql_text VARCHAR2(32767);
    BEGIN -- 10g see bug 5017909
      FOR i IN (SELECT DISTINCT piece, sql_text
                  FROM gv$sqltext_with_newlines
                WHERE sql_id = TRIM('&&sql_id.')
                ORDER BY 1, 2)
      LOOP
        IF :sql_text IS NULL THEN
          DBMS_LOB.CREATETEMPORARY(:sql_text, TRUE);
          DBMS_LOB.OPEN(:sql_text, DBMS_LOB.LOB_READWRITE);
        END IF;
        l_sql_text := REPLACE(i.sql_text, CHR(00), ' ');
        DBMS_LOB.WRITEAPPEND(:sql_text, LENGTH(l_sql_text), l_sql_text);
      END LOOP;
      IF :sql_text IS NOT NULL THEN
        DBMS_LOB.CLOSE(:sql_text);
      END IF;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('getting sql_text from memory: '||SQLERRM);
        :sql_text := NULL;
    END;
    /

-- get sql_text from awr
    BEGIN
      IF :sql_text IS NULL OR NVL(DBMS_LOB.GETLENGTH(:sql_text), 0) = 0 THEN
        SELECT REPLACE(sql_text, CHR(00), ' ')
          INTO :sql_text
          FROM dba_hist_sqltext
        WHERE sql_id = TRIM('&&sql_id.')
          AND sql_text IS NOT NULL
          AND ROWNUM = 1;
      END IF;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('getting sql_text from awr: '||SQLERRM);
        :sql_text := NULL;
    END;
    /

SELECT :sql_text FROM DUAL;

-- validate sql_text
    SET TERM ON;
    BEGIN
      IF :sql_text IS NULL THEN
        RAISE_APPLICATION_ERROR(-20100, 'SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).');
      END IF;
    END;
    /
    SET TERM OFF;

-- to avoid errors when sql_text lacks LFs and is more than 2000 bytes
    BEGIN
      :sql_text := REPLACE(:sql_text, ')', ')'||CHR(10));
      :sql_text := REPLACE(:sql_text, ',', ','||CHR(10));
      -- remove consecutive LFs
      :sql_text := REPLACE(:sql_text, CHR(10)||CHR(10)||CHR(10)||CHR(10)||CHR(10), CHR(10));
      :sql_text := REPLACE(:sql_text, CHR(10)||CHR(10)||CHR(10), CHR(10));
      :sql_text := REPLACE(:sql_text, CHR(10)||CHR(10), CHR(10));
    END;
    /

SELECT :sql_text FROM DUAL;

-- get other_xml from memory
    BEGIN
      FOR i IN (SELECT other_xml
                  FROM gv$sql_plan
                WHERE sql_id = TRIM('&&sql_id.')
                  AND plan_hash_value = TO_NUMBER(TRIM('&&plan_hash_value.'))
                  AND other_xml IS NOT NULL
                ORDER BY
                      child_number, id)
      LOOP
        :other_xml := i.other_xml;
        EXIT; -- 1st
      END LOOP;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('getting other_xml from memory: '||SQLERRM);
        :other_xml := NULL;
    END;
    /

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d692a27dc785683b30b328174c7a4800.html