Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

How to find Unused variables in procedure,function or package

prakashAug 21 2013 — edited Oct 18 2013

Hi all,

I want find out unused variables in procedure, function and package.

I have written below script for doing this ,but i am not getting the expected result.

Kindly help me to improve the below code ,so that it works as expected.

{code}

version details

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

PL/SQL Release 11.2.0.3.0 - Production

"CORE    11.2.0.3.0    Production"

TNS for Linux: Version 11.2.0.3.0 - Production

NLSRTL Version 11.2.0.3.0 - Production

{code}

{code}

What i Have tried is This.

DECLARE

  V_OBJECT_NAME VARCHAR2(30) :='PR_PRINT';

  V_OBJECT_TYPE VARCHAR2(30) :='PROCEDURE';

  CURSOR C1(CP_OBJECT_NAME VARCHAR2,CP_OBJECT_TYPE VARCHAR2)

  IS

    SELECT US.NAME,

      US.TYPE,

      US.LINE,

      REGEXP_SUBSTR(US.TEXT,'.* ') AS var_name

    FROM user_source US

    WHERE name=CP_OBJECT_NAME

    AND type  =CP_OBJECT_TYPE

    AND REGEXP_LIKE (TEXT,'(v_|g_|c_)','i')

    AND REGEXP_LIKE (TEXT,'^[^ ]')

    AND REGEXP_LIKE (TEXT,'^[^--;

  

  v_count NUMBER ;

BEGIN

  FOR i IN C1(V_OBJECT_NAME,V_OBJECT_TYPE)

  LOOP

    SELECT COUNT( *)

    INTO V_COUNT

    FROM USER_SOURCE US

    WHERE US.NAME=I.NAME

    AND REGEXP_LIKE(US.TEXT,i.var_name,'i' )

    AND US.LINE<>I.LINE;

  

    IF V_COUNT  =0 THEN

      DBMS_OUTPUT.PUT_LINE('variable '||I.VAR_NAME||'Is declared at line#'||I.LINE||' But no where used');

    END IF ;

  END LOOP;

EXCEPTION

WHEN OTHERS THEN

  DBMS_OUTPUT.PUT_LINE('p_err_code := '||SQLCODE||dbms_utility.format_Error_backtrace());

  DBMS_OUTPUT.PUT_LINE('p_err_msg := '||sqlerrm);

END ;

{code}

Thanks,

P Prakash

Comments

padders

Consider using PL/Scope and/or compiler warnings to determine this.

Alternatively some IDEs such as TOAD (and probably others) can report such.

Marwim

Hello,

as suggested by padders you can use PL/Scope, an example:

ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL';

CREATE OR REPLACE PACKAGE ui_test1 AS

    global_number   NUMBER := 9;

FUNCTION get_number

    RETURN NUMBER;

END ui_test1;

/

CREATE OR REPLACE PACKAGE BODY ui_test1 AS

PROCEDURE setNull

    (

     p_varchar          IN OUT VARCHAR2

    )

IS

BEGIN

    p_varchar := NVL(p_varchar,'NULL');

END setNull;

FUNCTION get_number

    RETURN NUMBER

IS

    FUNCTION setZero

        (

         p_number       IN NUMBER

        )

        RETURN NUMBER

    IS

    BEGIN

        RETURN NVL(p_number,0);

    END setZero;

BEGIN

    RETURN global_number;

END get_number;

END ui_test1;

/

SELECT  DISTINCT

        object_name

       ,object_type

       ,name

       ,type

       ,line

       ,col

FROM    all_identifiers obj

WHERE   obj.owner = USER

AND     obj.usage = 'DECLARATION'

AND     obj.object_name = 'UI_TEST1'

AND     NOT EXISTS (

            SELECT  1

            FROM    all_identifiers with_rh

            WHERE   obj.signature = with_rh.signature

            AND     with_rh.usage IN ('REFERENCE','CALL','ASSIGNMENT')

            )

ORDER BY TYPE

        ,object_name

        ,object_type

        ,name;

OBJECT_NAME  OBJECT_TYPE   NAME       TYPE       LINE COL

------------ ------------- ---------- ---------- ---- ---

UI_TEST1     PACKAGE       GET_NUMBER FUNCTION     11  10

UI_TEST1     PACKAGE BODY  SETZERO    FUNCTION     35  14

UI_TEST1     PACKAGE       UI_TEST1   PACKAGE       1   9

UI_TEST1     PACKAGE BODY  SETNULL    PROCEDURE    12  11

Regards

Marcus

BrianShaver

Thanks for the PL/Scope query example!

In general, if you want to be slightly more aggressive in finding and cleaning up the messy code, you should remove 'ASSIGNMENT' from the uses you're filtering out. While you can't blindly remove any lines returned by the resulting query, in most cases if a local variable only appears on the LHS of an assignment, it is useless and should be removed.

SELECT  DISTINCT

        object_name

       ,object_type

       ,name

       ,type

       ,line

       ,col

FROM    all_identifiers obj

WHERE   obj.owner = USER

AND     obj.usage = 'DECLARATION'

AND     obj.object_name = 'UI_TEST1'

AND     NOT EXISTS (

            SELECT  1

            FROM    all_identifiers with_rh

            WHERE   obj.signature = with_rh.signature

            AND     with_rh.usage IN ('REFERENCE','CALL')

            )

ORDER BY TYPE

        ,object_name

        ,object_type

        ,name;

1 - 3
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Nov 15 2013
Added on Aug 21 2013
3 comments
2,289 views