Fair warning ... this will be a long and confusing email.  However I'm about
to start sending hate mail to netscape for making debugging javascript in
ns6 sooo easy so I need a break.  Hopefully this will help because I looked
for a long time for an answer to this question and got nothing sufficient
back.  I'm using an example that I have on my system so you will need to
alter it according to your needs.

In this example we are calling a stored procedure in oracle to gather object
level security for the objects on a web page inside of a specific
application inside of a specific module ... sounds simple enough(ha!).  It
took a looooong time to figure this out.

Basically you need to create a dummy table to store the results of your
procedure and then return the data from that table as it applies to the
instance of the stored procedure call.

In this example that temp table has the following fields:
 PRV_AAL_NAME                   
 PRV_AAL_DATA_LEVEL_SECURITY
 PRV_AUS_OBJECT_PRIVS           
 PRV_FRU_UID                    
 PRV_PROCESS_ID                 
 PRV_CREATE_DATE                
 PRV_CREATE_USER                

PRV_PROCESS_ID is the key to getting the data back.  The rest of it is what
we want the stored procedure call to return.  In this example we pass the
stored procedure the results of the cold fusion function CreateUUID().

The stored procedure needs to be created as a package on the Oracle side and
I'll show you the code to do this in a bit ... but first here is how to call
the procedure from CF:

<CFSTOREDPROC PROCEDURE="PACK_REFCURSOR.GET_SECURITY_PRIVS2"
DATASOURCE="#request.site.DSN#" RETURNCODE="No">

<CFPROCPARAM TYPE="In" CFSQLTYPE="CF_SQL_INTEGER" VARIABLE="p_fru_uid"
VALUE="#client.fru_uid#" NULL="No">
<CFPROCPARAM TYPE="In" CFSQLTYPE="CF_SQL_INTEGER" VARIABLE="p_amt_id"
VALUE="#get_amt_id.amt_id#" NULL="No">
<CFPROCPARAM TYPE="In" CFSQLTYPE="CF_SQL_VARCHAR"
VARIABLE="p_prv_process_id" VALUE="#CreateUUID()#" NULL="No">
<CFPROCPARAM TYPE="Out" CFSQLTYPE="CF_SQL_REFCURSOR"
VARIABLE="object_privs">

<CFPROCRESULT NAME="ObjectPrivs">
</CFSTOREDPROC>

Let me explain the variables.  client.fru_uid is the user id.  amt_id is the
module id the user is trying to access.  CreateUUID corresponds to the
PRV_PROCESS_ID so we know what to get back and stick in the PROCRESULTS.

The package/procedure receives the variables and then executes a series of
queries that are dependent upon each other so there is a lot of querying and
then passing the variable to the next query.  I'm not going to explain all
of the queries involved here, but you should be able to pick through it to
pull something together.  This goes through and inserts a bunch of rows in
the prv table that consists of all the objects a user has rights to in
addition to roles that take precedence over the objects.  All of this works
amazingly fast and blows away the performance hit of doing it on the cf
side.  I'm not going to go into the data level security aspects at all
hehehe.

Here is the code that makes up the sql script that you run on oracle to
create the package/procedure:

CREATE OR REPLACE PACKAGE pack_refcursor AS
TYPE prv_tablerows IS REF CURSOR
RETURN prv%ROWTYPE;

PROCEDURE get_security_privs2(
  p_fru_uid             IN FRU.fru_uid%TYPE,
  p_amt_id              IN AMT.amt_id%TYPE,
  p_prv_process_id      IN PRV.prv_process_id%TYPE,
  object_privs          OUT prv_tablerows);
END pack_refcursor;
/

CREATE OR REPLACE PACKAGE BODY pack_refcursor AS


PROCEDURE get_security_privs2(
  p_fru_uid             IN FRU.fru_uid%TYPE,
  p_amt_id              IN AMT.amt_id%TYPE,
  p_prv_process_id      IN PRV.prv_process_id%TYPE,
  object_privs          OUT prv_tablerows)
IS
  l_aal_id                  AAL.aal_id%TYPE;
  l_aal_name                AAL.aal_name%TYPE;
  l_aal_data_level_security AAL.aal_data_level_security%TYPE;
  l_aus_object_privs        AUS.aus_object_privs%TYPE;
  
  
  /* Cursor to get the objects for this module. */
  CURSOR next_object
  IS
    SELECT 
      aal_id,
      aal_name,
      aal_data_level_security
    FROM
      aal
    WHERE
      aal_amt_id = p_amt_id;
  
  /* Cursor to get the user privileges for each object. */
  CURSOR next_user_privilege
  IS
    SELECT
      aus_object_privs
    FROM
      aus
    WHERE
      aus_fru_uid = p_fru_uid AND
      aus_ars_id = -1 AND
      aus_aal_id = l_aal_id;
      
  /* Cursor to get the role privileges for each object. */
  CURSOR next_role_privilege
  IS
    SELECT
      MAX(aus_object_privs)
    FROM
      aus,afl
    WHERE
      aus_fru_uid = -1 AND
      aus_ars_id = afl_ars_id AND
      afl_fru_uid  = p_fru_uid AND
      aus_aal_id = l_aal_id;
           

BEGIN

  /* Open cursors. */
  OPEN next_object;
  

  /* Loop through each object. */
  LOOP
    /* Initialize variables to clear previous values. */
    l_aal_id                  := NULL;
    l_aal_name                := NULL;
    l_aal_data_level_security := NULL;
    l_aus_object_privs        := NULL;

    /* Get the next object. */
    FETCH
      next_object
    INTO
      l_aal_id,
      l_aal_name,
      l_aal_data_level_security;
    EXIT WHEN next_object%NOTFOUND;
    
    /* Open the next_user_privilege cursor. */
    OPEN next_user_privilege;
      
    /* Get the next privilege for this user, for this object. */
    FETCH
      next_user_privilege
    INTO
      l_aus_object_privs;
    
    IF next_user_privilege%FOUND THEN
    
       INSERT INTO PRV(
        prv_aal_name,
        prv_aal_data_level_security,
        prv_aus_object_privs,
        prv_process_id,
        prv_fru_uid)
      VALUES(
        l_aal_name,
        l_aal_data_level_security,
        l_aus_object_privs,
        p_prv_process_id,
        p_fru_uid);
      
    /* If there is not a user level privilege (which takes precedence, 
       get the role based privileges. */
    ELSE
      /* Open the next_role_privilege cursor. */
      OPEN next_role_privilege;

      FETCH 
        next_role_privilege
      INTO
        l_aus_object_privs;
        
      INSERT INTO PRV(
        prv_aal_name,
        prv_aal_data_level_security,
        prv_aus_object_privs,
        prv_process_id,
        prv_fru_uid)
      VALUES(
        l_aal_name,
        l_aal_data_level_security,
        l_aus_object_privs,
        p_prv_process_id,
        p_fru_uid);
      
       CLOSE next_role_privilege;
     END IF;
     
  CLOSE next_user_privilege;
  
    
  END LOOP;
  
  /* Close cursors. */
  CLOSE next_object;
  
  /* Now get all the object privileges from the prv table. */
  OPEN object_privs FOR
    SELECT
      prv_aal_name,
      prv_aal_data_level_security,
      prv_aus_object_privs,
      prv_fru_uid,
      prv_process_id,
      prv_create_date,
      prv_create_user
    FROM
      prv
    WHERE
      prv_process_id = p_prv_process_id;
    
  /* Commit the transactions. */
  COMMIT;

  EXCEPTION
    WHEN OTHERS THEN
      /* Close cursor. */
      IF next_object%ISOPEN THEN
        CLOSE next_object;
      END IF;

END get_security_privs2;
END pack_refcursor;
/


-- ALTER PROCEDURE get_security_privs COMPILE
/




-----Original Message-----
From: Marsh, Jeffrey B [mailto:[EMAIL PROTECTED]]
Sent: Friday, May 18, 2001 11:33 AM
To: Fusebox
Subject: Oracle stored procedure


I'm attempting to use Oracle stored procedures for the first time. Oracle
SQL*Plus really stinks as an IDE. There has to be a better tool out there.
I've used Microsoft SQL Server in the past.

I'm having trouble writing a simple Oracle stored procedure to select data
from a table and return a record set. I read the KB articles. Is there still
no way to return an Oracle recordset? I was wondering if some kind soul
would post a short Oracle stored procedure to select data from a table and
post the CF code as well. I'm using a simple table to exercise several data
types. The table description is below. Thanks.

Name                            Null?    Type
 ------------------------------- -------- ----
 RECNO                           NOT NULL NUMBER
 LASTNAME                                 VARCHAR2(15)
 FIRSTNAME                                VARCHAR2(15)
 MIDDLEINITIAL                            CHAR(1)
 TEMPERATURE                              NUMBER(4,1)
 BIRTHDATE                                DATE
 UPDATEDBY                                VARCHAR2(10)
 MODIFIED                                 DATE

---
Jeffrey B. Marsh
Professionals built the Titanic.
Amateurs built the Ark.

****************************************************************************
This message is intended for the sole use of the individual and entity to
which it is addressed, and may contain information that is privileged,
confidential and exempt from disclosure under applicable law.  If you are
not the intended addressee, nor authorized to receive for the intended
addressee, you are hereby notified that you may not use, copy, disclose or
distribute to anyone the message or any information contained in the
message.  If you have received this message in error, please immediately
advise the sender by reply email and delete the message.  Thank you very
much.
****************************************************************************
****************************************************************************
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Structure your ColdFusion code with Fusebox. Get the official book at 
http://www.fusionauthority.com/bkinfo.cfm

Archives: http://www.mail-archive.com/[email protected]/
Unsubscribe: http://www.houseoffusion.com/index.cfm?sidebar=lists

Reply via email to