DBAsupport.com Forums - Powered by vBulletin
Results 1 to 6 of 6

Thread: PL/SQL Procedure Exec errors

  1. #1
    Join Date
    Nov 2003
    Posts
    31

    PL/SQL Procedure Exec errors

    Hi,

    Here is a PL/SQL procedure that I created. I am trying to execute it and I am running into the error described below. Any help would be greatly appreciated.

    Thanks,
    Sankar.


    CREATE OR REPLACE PROCEDURE proc_load_user_privileges

    AS





    /* The following cursor retrieves list of all of the privilege names which is

    basically all columns in table TEMP_NSDA_USER_PRIVILEGE except 'sun_id', 'node_id'

    */





    CURSOR cur_list_of_cols

    IS

    SELECT column_name

    FROM user_tab_columns

    WHERE table_name = 'TEMP_NSDA_USER_PRIVILEGE'

    AND column_name NOT IN ('SUN_ID', 'NODE_ID', 'OPERATION', 'FIRST_NM', 'LAST_NM', 'FUNCTIONAL_AREA_NM');



    -- Get all rows from the temporary table TEMP_NSDA_USER_PRIVILEGE

    CURSOR cur_temp_nsda_user_privilege

    IS

    SELECT *

    FROM TEMP_NSDA_USER_PRIVILEGE;



    v_current_sun_id VARCHAR2(30);

    v_current_node_id NUMBER(20);

    v_current_privilege_nm VARCHAR2(30);

    v_current_user_privilege_val VARCHAR2(30);

    v_current_column_name_in VARCHAR2(30);

    v_block_str VARCHAR2(500);

    v_dynamic_query_handle INTEGER;

    feedback INTEGER;

    v_curr VARCHAR2(30);

    v_operation VARCHAR2(30);

    v_first_nm VARCHAR2(30);

    v_last_nm VARCHAR2(30);

    v_functional_area VARCHAR2(30);











    BEGIN

    /*

    Loop thru all the rows of the temporary nsda_user_privilege

    table and for each row, using Dynamic-SQL query, figure out the value for

    the 'privilege name' columns i.e. VIEW_ATTACHMENT, FINANCE_VALIDATOR

    from the temporary table TEMP_NSDA_USER_PRIVILEGE..



    If the value for the 'privilege name' TEMP_NSDA_USER_PRIVILEGE is 'Y', then the

    column name of the table 'TEMP_NSDA_USER_PRIVILEGE' is set as value for the column 'privilege_nm'

    of the table 'NSDA_USER_PRIVILEGE'



    If the value for the 'privilege name' TEMP_NSDA_USER_PRIVILEGE is 'N' and is NOT NULL, then the

    column name of the table 'TEMP_NSDA_USER_PRIVILEGE' is set as value for the column 'privilege_nm'

    of the table 'NSDA_USER_PRIVILEGE'

    and the 'value' of the column name of the table 'TEMP_NSDA_USER_PRIVILEGE' is set as value for the

    column 'user_privilege_value'



    */





    --Begin looping thru all the records in the TEMP_NSDA_USER_PRIVILEGE Table

    FOR rec_temp_nsda_user_priv IN cur_temp_nsda_user_privilege

    LOOP

    v_current_sun_id := rec_temp_nsda_user_priv.sun_id;

    v_current_node_id := rec_temp_nsda_user_priv.node_id;

    v_operation := rec_temp_nsda_user_priv.operation;

    v_first_nm:= rec_temp_nsda_user_priv.first_nm;

    v_last_nm := rec_temp_nsda_user_priv.last_nm;

    v_functional_area:= rec_temp_nsda_user_priv.functional_area_nm;





    /* Take the user specific information and insert it into NSDA_USER table

    by calling the procedure 'insert_nsda_user'.



    */



    --EXEC insert_nsda_user_t(v_current_sun_id, v_first_nm, v_last_nm);





    /* If the current record in TEMP_NSDA_USER_PRIVILEGE table, is an update to

    one or more existing records, then all the records related to that

    sun_id are deleted..

    This approach avoids the processing needed to figure out which field within

    a record was updated..



    Also one record in TEMP_NSDA_USER_PRIVILEGE table

    results in multiple inserts or updates to the table NSDA_USER_PRIVILEGE.



    */



    IF v_operation = 'UPDATE' THEN

    DELETE FROM NSDA_USER_PRIVILEGE_T

    WHERE sun_id = v_current_sun_id;

    END IF;



    --Loop thru the list of column names of the table TEMP_NSDA_USER_PRIVILEGE

    FOR current_col IN cur_list_of_cols

    LOOP





    v_current_privilege_nm:= current_col.column_name;

    DBMS_OUTPUT.PUT_LINE('The current privilege name is ' || v_current_privilege_nm);



    v_block_str:= 'BEGIN

    SELECT v_current_privilege_nm INTO v_current_user_privilege_val '

    || 'FROM TEMP_NSDA_USER_PRIVILEGE

    WHERE sun_id = v_current_sun_id

    AND node_id = v_current_node_id;

    END;' ;



    EXECUTE IMMEDIATE v_block_str;

    --The dynamic SQL query related statements end here







    /* The short PL-SQL block below does the following:-

    Since the 'privilege name' related column names in TEMP_NSDA_USER_PRIVILEGE have

    underscore (e.g. FINANCE_VALIDATOR) character, they need to be replaced with whitespace

    to make them as e.g. FINANCE VALIDATOR,

    so that they can be stored as values for the column 'privilege_nm' in the table

    NSDA_USER_PRIVILEGE.



    */

    BEGIN

    SELECT

    REPLACE(v_current_privilege_nm, '_', ' ')

    INTO v_current_privilege_nm

    FROM DUAL;



    END;

    /* The short PL-SQL block ends here */



    --Checks to see the value of the user_privilege_value

    IF (v_current_user_privilege_val = 'Y')

    THEN

    INSERT INTO NSDA_USER_PRIVILEGE_T

    (sun_id, node_id, privilege_nm)

    VALUES

    (v_current_sun_id, v_current_node_id, v_current_privilege_nm);







    ELSIF (v_current_user_privilege_val IS NOT NULL) AND (v_current_user_privilege_val != 'N')

    THEN

    v_current_user_privilege_val:= TO_NUMBER(v_current_user_privilege_val);

    DBMS_OUTPUT.PUT_LINE('The value of current user privilege value is ' || TO_CHAR (v_current_user_privilege_val));





    INSERT INTO NSDA_USER_PRIVILEGE_T

    (sun_id, node_id, privilege_nm, user_privilege_value)

    VALUES

    (v_current_sun_id, v_current_node_id, v_current_privilege_nm,v_current_user_privilege_val );



    END IF;







    END LOOP;



    END LOOP;

    EXCEPTION

    WHEN OTHERS THEN

    DBMS_OUTPUT.PUT_LINE('The error is ' || SQLERRM);

    END proc_load_user_privileges;



    **************************************************
    The temp_nsda_user_privilege table is created as follows:

    create table temp_nsda_user_privilege
    (
    SUN_ID VARCHAR2(30),
    NODE_ID NUMBER(38),
    OPERATION VARCHAR2(10),
    FIRST_NM VARCHAR2(30),
    LAST_NM VARCHAR2(30),
    FUNCTIONAL_AREA_NM VARCHAR2(30),
    VIEW_ATTACHMENT VARCHAR2(40),
    FINANCE_VALIDATOR VARCHAR2(40),
    DEAL_MARGIN VARCHAR2(20),
    UPLOAD_ATTACHMENT VARCHAR2(20)
    )
    ==================================================
    HERE IS WHAT HAPPENS WHEN I CREATE & EXECUTE THIS PROCEDURE
    ==================================================

    SQL> @load_nsda_user_privileges-v2.sql
    165 /

    Procedure created.

    SQL> exec proc_load_user_privileges;
    The current privilege name is VIEW_ATTACHMENT
    The error is ORA-06550: line 4, column 33:
    PL/SQL: ORA-00904:
    "V_CURRENT_NODE_ID": invalid identifier
    ORA-06550: line 2, column 10:
    PL/SQL:
    SQL Statement ignored

    PL/SQL procedure successfully completed.
    Sankar B. Mandalika

  2. #2
    Join Date
    Nov 2002
    Location
    Geneva Switzerland
    Posts
    3,142
    v_block_str:= 'BEGIN
    SELECT v_current_privilege_nm INTO v_current_user_privilege_val '
    || 'FROM TEMP_NSDA_USER_PRIVILEGE
    WHERE sun_id = v_current_sun_id
    AND node_id = v_current_node_id;
    END;' ;

    EXECUTE IMMEDIATE v_block_str;
    That's not how you introduce parameters into dynamic SQL.

    Have a look at examples of bind variables here and USING: http://download-west.oracle.com/docs...ynam.htm#13131

    P.S. you don't need begin & end or the ;.

  3. #3
    Join Date
    Sep 2001
    Location
    Makati, Philippines
    Posts
    857
    I didn't read the whole procedure, I only quote this
    from Dapi's observation.

    try changing the value of v_block_str with this:
    v_block_str:=
    'SELECT '||v_current_privilege_nm||
    ' INTO '||v_current_user_privilege_val
    || ' FROM TEMP_NSDA_USER_PRIVILEGE WHERE sun_id = '||
    v_current_sun_id||' AND node_id = '||v_current_node_id;

  4. #4
    Join Date
    Nov 2002
    Location
    Geneva Switzerland
    Posts
    3,142
    reydp:
    a) that won't work - you can't use INTO like that
    b) better get into the habit of using bind variables now. Binds are you friends (like Google).

    It will need to be something like:
    Code:
    v_block_str:=
    'SELECT '||v_current_privilege_nm||
    ' FROM TEMP_NSDA_USER_PRIVILEGE WHERE sun_id = :1 AND node_id = :2';
    EXECUTE IMMEDIATE v_block_str
    INTO v_current_user_privilege_val
    USING v_current_sun_id, v_current_node_id ;
    Last edited by DaPi; 12-01-2004 at 01:42 AM.

  5. #5
    Join Date
    Sep 2001
    Location
    Makati, Philippines
    Posts
    857
    my bad Dapi,
    I should have known this, because I use this before.

  6. #6
    Join Date
    Nov 2004
    Location
    Mexicali.Mexico
    Posts
    13
    Avoid the use of sql concatenation in user-entered variables or you will be hacked (SQL Injection).

    Agree with DaPi, Bind are your friends.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Click Here to Expand Forum to Full Width