ITPub博客

首页 > 数据库 > Oracle > [20211230]完善sql_id脚本.txt

[20211230]完善sql_id脚本.txt

原创 Oracle 作者:lfree 时间:2021-12-31 09:19:17 1 删除 编辑

[20211230]完善sql_id脚本.txt

--//工作需要,有时候要抽取sql语句脚本。我自己经常使用两个脚本:sqlid.sql 和 sql_id.sql。

$ cat sqlid.sql
column sql_fulltext format a160
column sqltext format a255
set head off

prompt
prompt --sql_id = &&1
prompt
select to_char(replace(sql_fulltext,chr(13),'')) sqltext  from v$sql where  sql_id = '&&1' and rownum<=1
union
select to_char(replace(sql_text,chr(13),'')) sqltext  from dba_hist_sqltext where  sql_id = '&&1' and rownum<=1;
set head on

$ cat sql_id.sql
COLUMN SQL_FULLTEXT FORMAT A180
COLUMN SQLTEXT FORMAT A255

SELECT SQL_ID,HASH_VALUE,REPLACE(SQL_FULLTEXT,CHR(13),'') SQLTEXT FROM GV$SQLAREA WHERE SQL_ID='&1' AND ROWNUM=1;
PROMPT VIEW DBA_HIST_SQLTEXT
SELECT SQL_ID ,REPLACE(SQL_TEXT,CHR(13),'0')  SQLTEXT FROM DBA_HIST_SQLTEXT WHERE SQL_ID='&&1' AND ROWNUM=1;

--//为什么要有两个,主要原因一些开发仅仅使用chr(13)作为换行在PB下。导致我在sqlplus下经常看到的sql语句是乱的。
--//如果sql语句超长大于4000,我会直接使用sql_id.sql,但是输出两遍非常不好,必须重新改写sql_id脚本。

--//另外我不想输出两次,采用sqlid.sql脚本,必须使用union但是必须加to_char.如果不加会报错。

--//不加to_char使用union的情况:
SYS@127.0.0.1:17101/dyhis> @sql_id d3bxwwrcjp3tt
sql_id = d3bxwwrcjp3tt
select replace(sql_fulltext,chr(13),'') sqltext  from v$sql where  sql_id = 'd3bxwwrcjp3tt' and rownum<=1
       *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected - got CLOB

--//修改成union all可以通过,但是不是我需要的。但是无法解决sql语句超长问题。

> @sqlid d3bxwwrcjp3tt
select sql_id,hash_value,to_char(replace(sql_fulltext,chr(13),'')) sqltext  from v$sql where  sql_id = 'd3bxwwrcjp3tt' and rownum<=1
                         *
ERROR at line 1:
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 4552, maximum: 4000)

--//单独执行如下没有问题。
> select sql_id,hash_value,replace(sql_fulltext,chr(13),'') sqltext  from v$sql where  sql_id = 'd3bxwwrcjp3tt' and rownum<=1;
> select sql_id,hash_value,sql_fulltext sqltext  from v$sql where  sql_id = 'd3bxwwrcjp3tt' and rownum<=1;

--//根据需要修改如下:
$ cat sql_id.sql
--COLUMN SQL_FULLTEXT FORMAT A180
--COLUMN SQLTEXT FORMAT A255
--
--SELECT SQL_ID,HASH_VALUE,REPLACE(SQL_FULLTEXT,CHR(13),'') SQLTEXT FROM GV$SQLAREA WHERE SQL_ID='&1' AND ROWNUM=1;
--PROMPT VIEW DBA_HIST_SQLTEXT
--SELECT SQL_ID ,REPLACE(SQL_TEXT,CHR(13),'0')  SQLTEXT FROM DBA_HIST_SQLTEXT WHERE SQL_ID='&&1' AND ROWNUM=1;

--SELECT SQL_ID,TO_CHAR(SQL_FULLTEXT) SQLTEXT FROM GV$SQLAREA WHERE SQL_ID='&1' AND ROWNUM=1
--UNION
--SELECT SQL_ID,TO_CHAR(SQL_TEXT) SQLTEXT FROM DBA_HIST_SQLTEXT WHERE SQL_ID='&&1' AND ROWNUM=1;

SET LINESIZE 32767
--SET LINESIZE 4000
VAR V_SQL_FULLTEXT CLOB
COL SQL_FULLTEXT FOR A4000 WORD_WRAP

SET FEEDBACK OFF
SET SERVEROUTPUT ON

PROMPT
PROMPT --SQL_ID = &&1

DECLARE
    V_SQL_FULLTEXT   CLOB;
    V_COUNT          NUMBER;
BEGIN
    SELECT COUNT(*) INTO V_COUNT  FROM GV$SQLAREA WHERE SQL_ID = '&&1' AND ROWNUM=1;
    IF  V_COUNT=1
    THEN
        SELECT REPLACE (SQL_FULLTEXT||';', CHR(13), '') SQL_FULLTEXT INTO V_SQL_FULLTEXT FROM GV$SQLAREA WHERE SQL_ID = '&&1' AND ROWNUM = 1;
        DBMS_OUTPUT.PUT_LINE (V_SQL_FULLTEXT);
    ELSE
        SELECT COUNT(*)  INTO V_COUNT  FROM DBA_HIST_SQLTEXT WHERE SQL_ID='&&1' AND ROWNUM=1;
        IF  V_COUNT=1
        THEN
            SELECT REPLACE (SQL_TEXT||';',CHR(13),'')  INTO V_SQL_FULLTEXT  FROM DBA_HIST_SQLTEXT WHERE SQL_ID='&&1' AND ROWNUM=1;
            DBMS_OUTPUT.PUT_LINE (V_SQL_FULLTEXT);
        END IF;
    END IF;
    EXCEPTION WHEN NO_DATA_FOUND THEN
        NULL;
END;
/

PROMPT
SET SERVEROUTPUT OFF
SET FEEDBACK 6
SET LINESIZE 277

--//这样基本可以满足我工作需求。实际上使用replace也有现在,最大不能超过32767,一般很少出现怎么超长的sql语句。
--//另外必须设置SET LINESIZE 32767 , 不然输出的sql语句仅仅输出受linesize的限制。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-2850219/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7969284