<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Enkitec Blog</title>
	<atom:link href="http://blog.enkitec.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.enkitec.com</link>
	<description>The official blog of Enkitec</description>
	<lastBuildDate>Fri, 11 May 2012 21:56:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>ODBC Connection Fails for MS Access App on Citrix</title>
		<link>http://blog.enkitec.com/2012/05/odbc-connection-fails-for-ms-access-app-on-citrix/</link>
		<comments>http://blog.enkitec.com/2012/05/odbc-connection-fails-for-ms-access-app-on-citrix/#comments</comments>
		<pubDate>Fri, 11 May 2012 21:51:20 +0000</pubDate>
		<dc:creator>Toby Marks</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[access]]></category>
		<category><![CDATA[citrix]]></category>
		<category><![CDATA[odbc]]></category>
		<category><![CDATA[webapp]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[xenapp]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=634</guid>
		<description><![CDATA[(Original article on my Tumblr page.) I ran into an interesting problem recently when attempting to publish an MS Access application with Citrix XenApp. The application pulled data from an Oracle database, so an ODBC connection was created on the Citrix server. What we found was that when a non-privileged user tried to run the application, [...]]]></description>
			<content:encoded><![CDATA[<p>(<a href="http://tjmoracle.tumblr.com/post/22857143505/odbc-connection-fails-for-ms-access-app-on-citrix">Original article on my Tumblr page</a>.)</p>
<p>I ran into an interesting problem recently when attempting to publish an MS Access application with <a href="http://www.citrix.com/English/ps2/products/product.asp?contentID=186&amp;ntref=footer">Citrix XenApp</a>. The application pulled data from an Oracle database, so an ODBC connection was created on the Citrix server. What we found was that when a non-privileged user tried to run the application, the connection failed. When the Citrix server admin ran it, however, it worked. Furthermore, as long as the admin was logged in, anybody else could run the application successfully; when he logged out, the users’ connections broke again.</p>
<p><span id="more-634"></span></p>
<p>Since Access is not my area of expertise, we finally contacted Microsoft tech support after trying a few suggestions we dug up in our own research. The support analyst clued us in to the following solution, which I pulled from an Oracle Primavera <a href="http://docs.oracle.com/cd/E16688_01/Technical_Documentation/Terminal_Services_and_Citrix/Terminal%20Services%20and%20Citrix.pdf">setup document</a>.</p>
<p>From what I’ve seen on different support forums, this seems to be a pretty standard setup task when running Oracle on Windows over Citrix.</p>
<blockquote><p>If using an Oracle database platform, confirm [that] the Create Global Objects Windows Security Policy is set up on the Terminal Servers and add the domain Users or Groups of the end-users who will be accessing the published application. If the local security policy is not setup, the following steps can be used to add the policy:</p>
<ol>
<li>Click Start, Programs, Administrative Tools, and then click Local Security Policy.</li>
<li>Expand Local Policies, and then click User Rights Assignments.</li>
<li>In the right pane, double-click Create Global Objects.</li>
<li>In the Local Security Policy Setting dialogbox, click Add.</li>
<li>In the Select Users or Group dialog box, select the user group that these end users are a part of, click Add, and then click OK.</li>
<li>Click OK.</li>
</ol>
<p>If using an Oracle database platform, the Oracle client software also requires that you give the Authenticated User Group, Read and Execute privilege to the Oracle Home Directory and ALL its sub directories and files on the Terminal Servers.</p></blockquote>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2012/05/odbc-connection-fails-for-ms-access-app-on-citrix/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Discovering Command-line Java Profiling Tools</title>
		<link>http://blog.enkitec.com/2012/05/discovering-command-line-java-profiling-tools/</link>
		<comments>http://blog.enkitec.com/2012/05/discovering-command-line-java-profiling-tools/#comments</comments>
		<pubDate>Thu, 03 May 2012 20:14:58 +0000</pubDate>
		<dc:creator>Toby Marks</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[instrumentation]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jhat]]></category>
		<category><![CDATA[jmap]]></category>
		<category><![CDATA[jps]]></category>
		<category><![CDATA[jstack]]></category>
		<category><![CDATA[jstat]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[profiling]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=624</guid>
		<description><![CDATA[On my Tumblr blog I review a bevy of command-line Java profiling tools that you may not even know existed. They do, and they come included with the JDK! Read on&#8230;]]></description>
			<content:encoded><![CDATA[<p>On my <a target="_blank" href="http://tjmoracle.tumblr.com/">Tumblr blog</a> I review a bevy of command-line Java profiling tools that you may not even know existed. They do, and they come included with the JDK!</p>
<p><a target="_blank" href="http://tjmoracle.tumblr.com/post/22276471924/discovering-command-line-java-profiling-tools">Read on&#8230;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2012/05/discovering-command-line-java-profiling-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VMSTAT Tools</title>
		<link>http://blog.enkitec.com/2012/02/vmstat-tools/</link>
		<comments>http://blog.enkitec.com/2012/02/vmstat-tools/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 21:03:22 +0000</pubDate>
		<dc:creator>Jon Adams</dc:creator>
				<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=605</guid>
		<description><![CDATA[As database administrators, we should have the ability to review and evaluate resources on the underlying hardware where our databases reside. Often this review is done during times of stress when there is a current performance problem. Fortunately, there are a number of tools that are useful for determining the resource usage on these platforms. [...]]]></description>
			<content:encoded><![CDATA[<p>As database administrators, we should have the ability to review and evaluate resources on the underlying hardware where our databases reside.  Often this review is done during times of stress when there is a current performance problem.  Fortunately, there are a number of tools that are useful for determining the resource usage on these platforms.  I will focus on the VMSTAT tool in this blog entry.</p>
<p>VMSTAT is a tool on Unix type plaforms that provides an impressive amount of resource information, but is formatted in such a way that it can be difficult to read much less determine when the snapshot occurred if looking at historic snapshots.  Here is an example</p>
<p>[root@new-host ~]# vmstat 2<br />
procs &#8212;&#8212;&#8212;&#8211;memory&#8212;&#8212;&#8212;- &#8212;swap&#8211; &#8212;&#8211;io&#8212;- &#8211;system&#8211; &#8212;&#8211;cpu&#8212;&#8212;<br />
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st<br />
 0  0      0 1916352  39376 906944    0    0   186    39 1024 1139  1  2 93  4  0<br />
 1  0      0 1916352  39384 906968    0    0     0    76 1015 1203  0  2 95  4  0<br />
 0  0      0 1916260  39392 906976    0    0     0    58 1014 1118  0  2 98  0  0</p>
<p>Through some simple Unix scripting commands, you can get more user-friendly information from this tool.</p>
<p>The vmstat_tool.sh script below works for most Linux versions:</p>
<p>#!/bin/sh<br />
#vmstat_tool.sh<br />
#vmstat parser script. Makes the information easily readable.</p>
<p>#Ensure that the number of loops and delay parameters<br />
#were passed to this script<br />
if [ $# -ne 2 ]<br />
then<br />
  echo &#8220;Usage: $0 <loop_count> <delay_in_seconds_between_loops>&#8221;<br />
  exit<br />
fi</p>
<p>export LPCNT=$1<br />
export DLAY=$2</p>
<p>c=0</p>
<p>while [ "$c" -lt $LPCNT ]<br />
do<br />
date<br />
vmstat | tail -n 1 | awk &#8216;{printf(&#8220;%d processes are waiting\n%d processes are blocked\n%d virtual memory used, %d idle memory, %d buffer memory, %d cache memory\n%d memory swapped in from disk, %d memory swapped out to disk\n%d blocks per second written\n%d blocks per second read\n%d interrupts per second\n%d context switches per second\nCPU usage: %d%% (user, non-kernel), %d%% (system, kernel), %d%% idle, %d%% wait\n\n&#8221;,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16)}&#8217;</p>
<p>sleep $DLAY<br />
c=$((c+1))<br />
done</p>
<p>Sample Output (Single Loop):</p>
<p>Sat Feb 18 11:15:48 PST 2012<br />
1 processes are waiting<br />
0 processes are blocked<br />
0 virtual memory used, 1990308 idle memory, 32964 buffer memory, 843564 cache memory<br />
0 memory swapped in from disk, 0 memory swapped out to disk<br />
928 blocks per second written<br />
75 blocks per second read<br />
1062 interrupts per second<br />
1128 context switches per second<br />
CPU usage: 4% (user, non-kernel), 2% (system, kernel), 77% idle, 17% wait</p>
<p>As you can see. the output is much more readable than the regular vmstat output.</p>
<p>Should you need to do more than just a cursory examination of the VMSTAT output, you can use these scripts to generate an output file for examination with the following method:</p>
<p>nohup vmstat_tool.sh 288 300 > ./vmstat.log &#038;</p>
<p>In the above example, you are using the native nohup command to run the vmstat_tool.sh script to loop every 5 minutes (300 seconds) for 24 hours (288 5-minute loops).  The output will to the vmstat.log script in the local directory and will run in the background by using &#8216;&#038;&#8217; at the end of the command.  Examining the output is a simple matter of using the native cat and grep commands in the following manner:</p>
<p>cat ./vmstat.log | grep &#8220;processes are waiting&#8221; | more</p>
<p>Sample Output:</p>
<p>0 processes are waiting 0 processes are blocked<br />
0 processes are waiting 0 processes are blocked<br />
0 processes are waiting 0 processes are blocked<br />
0 processes are waiting 0 processes are blocked<br />
0 processes are waiting 0 processes are blocked<br />
0 processes are waiting 0 processes are blocked<br />
0 processes are waiting 0 processes are blocked<br />
0 processes are waiting 0 processes are blocked</p>
<p>You can now see the output of the first line of the VMSTAT tool scrolled one screen at a time.  If you see a line that has some abnormal values, you can then use the vi utility to zero in on that particular value and get the timestamp from it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2012/02/vmstat-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My crsstat script: Improved Formatting of crs_stat on 10g and 11g</title>
		<link>http://blog.enkitec.com/2011/10/my-crsstat-script-improved-formatting-of-crs_stat-on-10g-and-11g/</link>
		<comments>http://blog.enkitec.com/2011/10/my-crsstat-script-improved-formatting-of-crs_stat-on-10g-and-11g/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 03:08:53 +0000</pubDate>
		<dc:creator>Paul Elbow</dc:creator>
				<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=525</guid>
		<description><![CDATA[My crsstat shows a tabular format of CRS or HAS resources (i.e. Cluster 10gR2-11gR2 or ASM/Single instance scenario 11gR2). It has been a work in progress for a while. When I first started working with 10gR2 RAC, I quickly discovered that I didn&#8217;t quite like the formatting of the default crs_stat -t output, so I [...]]]></description>
			<content:encoded><![CDATA[<p>My crsstat shows a tabular format of CRS or HAS resources (i.e. Cluster 10gR2-11gR2 or ASM/Single instance scenario 11gR2).  It has been a work in progress for a while.  When I first started working with 10gR2 RAC, I quickly discovered that I didn&#8217;t quite like the formatting of the default crs_stat -t output, so I wrote my first version of the crsstat script, which consisted of a korn shell script and an awk script (which gave pretty close to the same output as the current version).  I enhanced it at some point to show a different color, if the state didn&#8217;t match the target state.  Then 11gR2 came out and I really didn&#8217;t like the output, so I sat down and wrote the awk script to format the 11gR2 output and added a variable at the top to choose which awk script.  One of my colleagues saw it and liked the output, so I shared it; however, he asked if I could simplify the installation, as at that time you had to set the location of the script, whether it was 10g or 11g, and the location of the CRS_HOME.  Finally, I sat down and decided to make it as universal and easy to use, as I could by adding the awk scripts as variables within the ksh script and adding a section to attempt to determine the CRS or HAS home automatically.  It seems to work fairly well and several of my colleagues have been using it, so I thought I would share it more universally.  Hope everyone finds it useful!<br />
<span id="more-525"></span></p>
<h1>How it Works</h1>
<p>It should work with 10gR2-11gR2 without changes.  The first time is run, it will attempt to identify the Grid Infrastructure / CRS home and the version that is being used (CRS/HAS must be up for it to gather)- it takes that information and writes the info to a crsstat.env located in the same location as the script.  It only gathers the information the first time, so if you upgrade the Oracle software you will want to remove the crsstat.env and allow the script to re-gather the information.</p>
<p>The output of the script assumes a term width of 132 and attempts to highlight possible issues, by showing in RED those resources with a target of ONLINE and a state of OFFLINE.  You can also pass in “search criteria” as the first and only parameter.</p>
<p>Also of note, per Oracle support document 1086563.1, the “State Details” output in 11gR2 could show incorrect information, such as, “Instance Shutdown” even though it is up and running correctly.</p>
<p>Under the covers, the script is utilizing the “crs_stat -t” in 10gR2/11gR1 and “crsctl status resource -t” and then awks their output to create the tabular format.  It has been used on AIX and Linux (SuSE, Red Hat, Oracle).</p>
<h1>How to Install</h1>
<h2>Pre-requisite to Installation:</h2>
<p>1. CRS/HAS must be running<br />
2. The location of the crsstat script must be writable by the user that will run the installation (either root or your oracle user)</p>
<h2>Installation Location:</h2>
<p>Generally, it is practical to put the crsstat script in the /usr/local/bin directory, so everyone will have access (in most users path).  Make sure the crsstat.env file can be created in the /usr/local/bin directory the first time the script is run.  If it is preferred to put it an alternate location, choose a location that is accessible by your Unix users that should be able to list the CRS or HAS resources (i.e. in their PATH).</p>
<h2>Installation Process:</h2>
<p>1) Copy the installation script from this link <a href="http://blog.enkitec.com/wp-content/uploads/2012/04/crsstat.v1.2.1.zip">http://blog.enkitec.com/wp-content/uploads/2012/04/crsstat.v1.2.1.zip</a><br />
2) Do a &#8220;cp crsstat.v1.2.1.zip /usr/local/bin/&#8221;<br />
3) As root run the crsstat and a &#8220;crsstat.env&#8221; file is created:</p>
<pre style="padding-left: 60px;"># cd /usr/local/bin
# unzip crsstat.v1.2.1.zip
# chmod 755 crsstat
# ./crsstat</pre>
<p><em style="padding-left: 65px;">Output like example below&#8230;</em></p>
<pre style="padding-left: 60px;"># chmod 644 crsstat.env</pre>
<p>4) Verify that the crsstat.env file has two entries like the following:<br />
GRID_HOME=/u01/app/oracle/product/11.2.0/grid<br />
GRID_VER=11.2</p>
<h1>Example Usage</h1>
<p>Basic Usage (note that the dbfs filesystem is offline when it should be online, thus it is highlight in red):</p>
<pre style="padding-left: 30px; background-color: #000000;"><span style="color: #ffffff; background-color: #000000;">$ crsstat

Resource Name                            Resource Type  Target       State        Node            State Details
---------------------------------------- -------------- ------------ ------------ --------------- --------------
ora.DATA.dg                              diskgroup      ONLINE       ONLINE       tstdb01
ora.DATA.dg                              diskgroup      ONLINE       ONLINE       tstdb02
ora.LISTENER.lsnr                        Listener       ONLINE       ONLINE       tstdb01
ora.LISTENER.lsnr                        Listener       ONLINE       ONLINE       tstdb02
ora.LISTENER_SCAN1.lsnr                  SCAN Listener  ONLINE       ONLINE       tstdb02
ora.LISTENER_SCAN2.lsnr                  SCAN Listener  ONLINE       ONLINE       tstdb01
ora.LISTENER_SCAN3.lsnr                  SCAN Listener  ONLINE       ONLINE       tstdb01
ora.RECO.dg                              diskgroup      ONLINE       ONLINE       tstdb01
ora.RECO.dg                              diskgroup      ONLINE       ONLINE       tstdb02
ora.SYSTEM.dg                            diskgroup      ONLINE       ONLINE       tstdb01
ora.SYSTEM.dg                            diskgroup      ONLINE       ONLINE       tstdb02
ora.asm                                  ASM            ONLINE       ONLINE       tstdb01
ora.asm                                  ASM            ONLINE       ONLINE       tstdb02
ora.cvu                                  cvu            ONLINE       ONLINE       tstdb01
ora.dbfs.db                              database       ONLINE       ONLINE       tstdb01         Open
ora.dbfs.db                              database       ONLINE       ONLINE       tstdb02         Open
<span style="color: #ff0000;">ora.dbfs.filesystem                                     ONLINE       OFFLINE</span>
<span style="color: #ff0000;">ora.dbfs.filesystem                                     ONLINE       OFFLINE</span>
ora.demo.db                              database       ONLINE       ONLINE       tstdb01         Open
ora.demo.db                              database       ONLINE       ONLINE       tstdb02         Open
ora.demo.workshop.svc                    service        ONLINE       ONLINE       tstdb01
ora.demo.workshop.svc                    service        ONLINE       ONLINE       tstdb02
ora.tstdb01.vip                          Cluster VIP    ONLINE       ONLINE       tstdb01
ora.tstdb02.vip                          Cluster VIP    ONLINE       ONLINE       tstdb02
ora.net1.network                         Network (VIP)  ONLINE       ONLINE       tstdb01
ora.net1.network                         Network (VIP)  ONLINE       ONLINE       tstdb02
ora.ons                                  Ora Notif Svc  ONLINE       ONLINE       tstdb01
ora.ons                                  Ora Notif Svc  ONLINE       ONLINE       tstdb02
ora.registry.acfs                        registry       ONLINE       ONLINE       tstdb01
ora.registry.acfs                        registry       ONLINE       ONLINE       tstdb02
ora.scan1.vip                            SCAN VIP       ONLINE       ONLINE       tstdb02
ora.scan2.vip                            SCAN VIP       ONLINE       ONLINE       tstdb01
ora.scan3.vip                            SCAN VIP       ONLINE       ONLINE       tstdb01
ora.test.db                              database       OFFLINE      OFFLINE
ora.test.db                              database       OFFLINE      OFFLINE
</span></pre>
<p>A couple of examples using the search key:</p>
<pre style="padding-left: 30px; background-color: #000000;"><span style="color: #ffffff; background-color: #000000;">$ crsstat service

Resource Name                            Resource Type  Target       State        Node            State Details
---------------------------------------- -------------- ------------ ------------ --------------- --------------
ora.demo.workshop.svc                    service        ONLINE       ONLINE       tstdb01
ora.demo.workshop.svc                    service        ONLINE       ONLINE       tstdb02

$ crsstat demo

Resource Name                            Resource Type  Target       State        Node            State Details
---------------------------------------- -------------- ------------ ------------ --------------- --------------
ora.demo.db                              database       ONLINE       ONLINE       enkdb01         Open
ora.demo.db                              database       ONLINE       ONLINE       enkdb02         Open
ora.demo.workshop.svc                    service        ONLINE       ONLINE       enkdb01
ora.demo.workshop.svc                    service        ONLINE       ONLINE       enkdb02
</span></pre>
<p>Another example, as sometimes when there are many databases it is useful to pipe the output to grep:</p>
<pre style="padding-left: 30px; background-color: #000000;"><span style="color: #ffffff; background-color: #000000;">$ crsstat database | grep -i offline

ora.test.db                              database       OFFLINE      OFFLINE
ora.test.db                              database       OFFLINE      OFFLINE
</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2011/10/my-crsstat-script-improved-formatting-of-crs_stat-on-10g-and-11g/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Table Functions: 9i Feature Worth Revisiting (Part 2)</title>
		<link>http://blog.enkitec.com/2011/10/table-functions-9i-feature-worth-revisiting-part-2/</link>
		<comments>http://blog.enkitec.com/2011/10/table-functions-9i-feature-worth-revisiting-part-2/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 22:14:25 +0000</pubDate>
		<dc:creator>Toby Marks</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[9i]]></category>
		<category><![CDATA[PIPE ROW]]></category>
		<category><![CDATA[PIPELINED]]></category>
		<category><![CDATA[TABLE]]></category>
		<category><![CDATA[Table Functions]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=470</guid>
		<description><![CDATA[In part I of this series I showed a simple example of how table functions can be used to treat PL/SQL collection types as tables in a SQL query. We used a nested table collection type to which we manually added a few entries. In this example, I intend to show a more practical use [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://blog.enkitec.com/?p=407">part I of this series</a> I showed a simple example of how table functions can be used to treat PL/SQL collection types as tables in a SQL query. We used a nested table collection type to which we manually added a few entries. In this example, I intend to show a more practical use of table functions using all three PL/SQL collection types: associative arrays, nested tables, and VARRAYs.</p>
<p><span id="more-470"></span></p>
<p>Let&#8217;s revisit a use case I alluded to in my earlier blog entry: incorporating LDAP data into a query. Suppose your task is to code a custom authorization scheme for an enterprise application reporting system. You want row access to be determined by a user&#8217;s group memberships in the company&#8217;s Active Directory server. If a user is assigned to &#8220;the Company A group&#8221; in Active Directory, he gets to see Company A&#8217;s data. You can configure that kind of restriction at a database level using <a href="http://www.oracle.com/technetwork/database/security/index-088277.html">Oracle&#8217;s Virtual Private Database</a> feature. Configuring VPD is beyond the scope of this blog entry, but ultimately you will be associating a table to a portion of a SQL WHERE clause that gets appended to every query written against that table. You can find more documentation on VPD <a href="http://download.oracle.com/docs/cd/B28359_01/network.111/b28531/vpd.htm">on the OTN site</a>. In this case, let&#8217;s assume you know that another team has written a PL/SQL database package to query data from Active Directory, and you want to make use of that code. The only problem is that all the functions in that package return collections of various types, and you need to be able to access that information from the WHERE clause you are building with VPD. This is where table functions come in handy.</p>
<p>Let&#8217;s begin by setting up our example schema. We&#8217;ll be looking at client sales data. First, let&#8217;s set up our clients.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code13'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47013"><td class="code" id="p470code13"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> clients <span style="color: #66cc66;">&#40;</span>
  client_id NUMBER<span style="color: #66cc66;">,</span>
  client_name VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> clients <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Timco Industries'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> clients <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Moneybros'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> clients <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">300</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'The Monacle Corporation'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> clients <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">400</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Schmapple'</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>We also need application users who will be logging in to view the report data. We&#8217;ll assume each application user is uniquely linked to a user in Active Directory via the external_id column.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code14'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47014"><td class="code" id="p470code14"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> users <span style="color: #66cc66;">&#40;</span>
  sequence_number NUMBER<span style="color: #66cc66;">,</span>
  user_name VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  external_id VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  first_name VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  last_name VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'JACKA'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'jaugusti'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Jack'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Augustine'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'KENKI'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'kkidd'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Ken'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Kidd'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'BRIAH'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'bhill'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Brian'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Hill'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> users <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'KEOVO'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'kvongkas'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Keo'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Vongkaseum'</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>Finally, we need a data table on which to report.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code15'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47015"><td class="code" id="p470code15"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> quarterly_sales_data <span style="color: #66cc66;">&#40;</span>
  sequence_number NUMBER<span style="color: #66cc66;">,</span>
  client_id NUMBER<span style="color: #66cc66;">,</span>
  sales_year NUMBER<span style="color: #66cc66;">,</span>
  sales_quarter NUMBER<span style="color: #66cc66;">,</span>
  sales_amount NUMBER<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">20000</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">17500</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">100</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">33000</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">200</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">4500</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">200</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">7000</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">6</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">200</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">6300</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">7</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">300</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">11100</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">8</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">300</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">12800</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">300</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">14000</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">400</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">55600</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">400</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">80000</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">400</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">2011</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">78500</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>Our basic report query will look something like this:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code16'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47016"><td class="code" id="p470code16"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> client_name<span style="color: #66cc66;">,</span> sales_year<span style="color: #66cc66;">,</span> sales_quarter<span style="color: #66cc66;">,</span> sales_amount
  <span style="color: #993333; font-weight: bold;">FROM</span> quarterly_sales_data <span style="color: #993333; font-weight: bold;">NATURAL</span> <span style="color: #993333; font-weight: bold;">JOIN</span> clients;</pre></td></tr></table></div>

<p>Our Active Directory groups will be TIMCO_GRP, MONEYBROS_GRP, MONACLE_GRP, and SCHMAPPLE_GRP. If a user belongs to one or more of these groups, he has permission to view the respective client&#8217;s data.</p>
<p>Now we need a function that returns data from Active Directory. Just to keep it simple we will create a package that hardcodes the group memberships and returns them as collections of various types. We will then look at how table functions can be used to transform each one of those collections into an aggregate result set. (NOTE: querying LDAP directories from PL/SQL is not too difficult, and might serve as the basis for a future blog entry.)</p>
<p>Here&#8217;s our function. We&#8217;ve placed it in a package called LDAP_UTIL.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code17'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47017"><td class="code" id="p470code17"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> PACKAGE ldap_util <span style="color: #993333; font-weight: bold;">AS</span>
&nbsp;
  TYPE ldap_entry_typ <span style="color: #993333; font-weight: bold;">IS</span> RECORD <span style="color: #66cc66;">&#40;</span>
    cn VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    description VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1000</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    distinguished_name VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    name VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    samaccountname VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  TYPE ldap_groups_nt <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">TABLE</span> OF ldap_entry_typ;
  TYPE ldap_groups_aa <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">TABLE</span> OF ldap_entry_typ <span style="color: #993333; font-weight: bold;">INDEX</span> <span style="color: #993333; font-weight: bold;">BY</span> PLS_INTEGER;
  TYPE ldap_groups_va <span style="color: #993333; font-weight: bold;">IS</span> VARRAY<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span> of ldap_entry_typ;
&nbsp;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_nt <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_nt;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_aa <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_aa;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_va <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_va;
&nbsp;
END ldap_util;
<span style="color: #66cc66;">/</span>
<span style="color: #993333; font-weight: bold;">SHOW</span> ERRORS
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> PACKAGE BODY ldap_util <span style="color: #993333; font-weight: bold;">AS</span>
&nbsp;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_nt <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_nt <span style="color: #993333; font-weight: bold;">IS</span>
    l_groups ldap_groups_nt :<span style="color: #66cc66;">=</span> ldap_groups_nt<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
  BEGIN
    CASE p_user
      WHEN <span style="color: #ff0000;">'jaugusti'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Timco Industries account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=TIMCO_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'kkidd'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Moneybros account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONEYBROS_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'bhill'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Timco Industries account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=TIMCO_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Monacle Corporation account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONACLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'kvongkas'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Moneybros account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONEYBROS_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Monacle Corporation account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONACLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Schmapple account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=SCHMAPPLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
&nbsp;
    END CASE;
    <span style="color: #993333; font-weight: bold;">RETURN</span> l_groups;
  END get_user_groups_nt;
&nbsp;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_aa <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_aa <span style="color: #993333; font-weight: bold;">IS</span>
    l_groups ldap_groups_aa;
  BEGIN
    CASE p_user
      WHEN <span style="color: #ff0000;">'jaugusti'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Timco Industries account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=TIMCO_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'kkidd'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Moneybros account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONEYBROS_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'bhill'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Timco Industries account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=TIMCO_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Monacle Corporation account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONACLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'kvongkas'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Moneybros account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONEYBROS_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Monacle Corporation account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONACLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Schmapple account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=SCHMAPPLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
&nbsp;
    END CASE;
    <span style="color: #993333; font-weight: bold;">RETURN</span> l_groups;
  END get_user_groups_aa;
&nbsp;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_va <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_va <span style="color: #993333; font-weight: bold;">IS</span>
    l_groups ldap_groups_va :<span style="color: #66cc66;">=</span> ldap_groups_va<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
  BEGIN
    CASE p_user
      WHEN <span style="color: #ff0000;">'jaugusti'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Timco Industries account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=TIMCO_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'kkidd'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Moneybros account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONEYBROS_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'bhill'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Timco Industries account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=TIMCO_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'TIMCO_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Monacle Corporation account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONACLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
&nbsp;
      WHEN <span style="color: #ff0000;">'kvongkas'</span> THEN
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Moneybros account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONEYBROS_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONEYBROS_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Monacle Corporation account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=MONACLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'MONACLE_GRP'</span>;
&nbsp;
        l_groups<span style="color: #66cc66;">.</span>extend;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>cn :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>description :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Employees working on the Schmapple account.'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>distinguished_name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'CN=SCHMAPPLE_GRP,OU=Global Groups,DC=acme,DC=com'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>name :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
        l_groups<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>samaccountname :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span>;
&nbsp;
    END CASE;
    <span style="color: #993333; font-weight: bold;">RETURN</span> l_groups;
  END get_user_groups_va;
&nbsp;
END ldap_util;
<span style="color: #66cc66;">/</span>
<span style="color: #993333; font-weight: bold;">SHOW</span> ERRORS</pre></td></tr></table></div>

<p>As you can see, LDAP_UTIL has three functions that return the three kinds of collections in PL/SQL: nested tables, associative arrays, and varrays.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code18'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47018"><td class="code" id="p470code18"><pre class="sql" style="font-family:monospace;">  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_nt <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_nt;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_aa <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_aa;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_va <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_groups_va;</pre></td></tr></table></div>

<p>The collections consist of a group of records representing &#8220;group&#8221; data from Active Directory.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code19'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47019"><td class="code" id="p470code19"><pre class="sql" style="font-family:monospace;">  TYPE ldap_entry_typ <span style="color: #993333; font-weight: bold;">IS</span> RECORD <span style="color: #66cc66;">&#40;</span>
    cn VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    description VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1000</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    distinguished_name VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    name VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    samaccountname VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>The p_user parameter would be the user&#8217;s network id, corresponding to the sAMAccountName attribute in Active Directory; since we&#8217;re hardcoding group data this is not important to us at the moment. The point is you pass in a username and you get a collection of groups.</p>
<p>Using the same technique we demonstrated in part one, we now create a wrapper package of pipelined functions to transform the collection data into something we can query &#8211; an aggregate result set.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code20'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47020"><td class="code" id="p470code20"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> PACKAGE ldap_util_pipelined <span style="color: #993333; font-weight: bold;">AS</span>
&nbsp;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_nt <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_nt PIPELINED;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_aa <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_nt PIPELINED;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_va <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_va PIPELINED;
&nbsp;
END ldap_util_pipelined;
<span style="color: #66cc66;">/</span>
<span style="color: #993333; font-weight: bold;">SHOW</span> ERRORS
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> PACKAGE BODY ldap_util_pipelined <span style="color: #993333; font-weight: bold;">AS</span>
&nbsp;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_nt <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> 
  <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_nt PIPELINED <span style="color: #993333; font-weight: bold;">IS</span>
    l_groups ldap_util<span style="color: #66cc66;">.</span>ldap_groups_nt;
  BEGIN
    l_groups :<span style="color: #66cc66;">=</span> ldap_util<span style="color: #66cc66;">.</span>get_user_groups_nt<span style="color: #66cc66;">&#40;</span>p_user<span style="color: #66cc66;">&#41;</span>;
    <span style="color: #993333; font-weight: bold;">FOR</span> i <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">..</span> l_groups<span style="color: #66cc66;">.</span>count LOOP
      PIPE ROW <span style="color: #66cc66;">&#40;</span>l_groups<span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
    END LOOP;
    <span style="color: #993333; font-weight: bold;">RETURN</span>;
  END get_user_groups_nt;
&nbsp;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_aa <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> 
  <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_nt PIPELINED <span style="color: #993333; font-weight: bold;">IS</span>
    l_groups ldap_util<span style="color: #66cc66;">.</span>ldap_groups_aa;
  BEGIN
    l_groups :<span style="color: #66cc66;">=</span> ldap_util<span style="color: #66cc66;">.</span>get_user_groups_aa<span style="color: #66cc66;">&#40;</span>p_user<span style="color: #66cc66;">&#41;</span>;
    <span style="color: #993333; font-weight: bold;">FOR</span> i <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">..</span> l_groups<span style="color: #66cc66;">.</span>count LOOP
      PIPE ROW <span style="color: #66cc66;">&#40;</span>l_groups<span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
    END LOOP;
    <span style="color: #993333; font-weight: bold;">RETURN</span>;
  END get_user_groups_aa;
&nbsp;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_va <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> 
  <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_va PIPELINED <span style="color: #993333; font-weight: bold;">IS</span>
    l_groups ldap_util<span style="color: #66cc66;">.</span>ldap_groups_va;
  BEGIN
    l_groups :<span style="color: #66cc66;">=</span> ldap_util<span style="color: #66cc66;">.</span>get_user_groups_va<span style="color: #66cc66;">&#40;</span>p_user<span style="color: #66cc66;">&#41;</span>;
    <span style="color: #993333; font-weight: bold;">FOR</span> i <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">..</span> l_groups<span style="color: #66cc66;">.</span>count LOOP
      PIPE ROW <span style="color: #66cc66;">&#40;</span>l_groups<span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
    END LOOP;
    <span style="color: #993333; font-weight: bold;">RETURN</span>;
  END get_user_groups_va;
&nbsp;
END ldap_util_pipelined;
<span style="color: #66cc66;">/</span>
<span style="color: #993333; font-weight: bold;">SHOW</span> ERRORS</pre></td></tr></table></div>

<p>Note the return types of the three functions in ldap_util_pipelined.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code21'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47021"><td class="code" id="p470code21"><pre class="sql" style="font-family:monospace;">  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_nt <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_nt PIPELINED;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_aa <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_nt PIPELINED;
  <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_user_groups_va <span style="color: #66cc66;">&#40;</span>p_user VARCHAR2<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURN</span> ldap_util<span style="color: #66cc66;">.</span>ldap_groups_va PIPELINED;</pre></td></tr></table></div>

<p>The first two return a nested table collection, while the third returns a VARRAY. These two collections can be pipelined because they correspond to native SQL datatypes in Oracle; not so for associative arrays. In order to pipeline the associative array returned from ldap_util.get_user_groups_aa, we need to map that collection to one of the other types. Here, we map it to a nested table. The iterative logic is the same, though, as the other two functions.</p>
<p>Now we can verify that our approach worked by issuing some simple queries, supported by the SQL &#8220;TABLE&#8221; construct.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code22'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47022"><td class="code" id="p470code22"><pre class="sql" style="font-family:monospace;">SQL<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">select</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">from</span> <span style="color: #993333; font-weight: bold;">table</span><span style="color: #66cc66;">&#40;</span>ldap_util_pipelined<span style="color: #66cc66;">.</span>get_user_groups_nt<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'jaugusti'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
CN        DESCRIPTION                                        DISTINGUISHED_NAME                            NAME      SAMACCOUN
<span style="color: #808080; font-style: italic;">--------- -------------------------------------------------- --------------------------------------------- --------- ---------</span>
TIMCO_GRP Employees working <span style="color: #993333; font-weight: bold;">on</span> the Timco Industries account<span style="color: #66cc66;">.</span> CN<span style="color: #66cc66;">=</span>TIMCO_GRP<span style="color: #66cc66;">,</span>OU<span style="color: #66cc66;">=</span>Global Groups<span style="color: #66cc66;">,</span>DC<span style="color: #66cc66;">=</span>acme<span style="color: #66cc66;">,</span>DC<span style="color: #66cc66;">=</span>com  TIMCO_GRP TIMCO_GRP</pre></td></tr></table></div>

<p>As you can see, the individual attributes of the record structure form the columns of our new table, and we can reference those columns directly, if we wish.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code23'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47023"><td class="code" id="p470code23"><pre class="sql" style="font-family:monospace;">SQL<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">select</span> cn <span style="color: #993333; font-weight: bold;">from</span> <span style="color: #993333; font-weight: bold;">table</span><span style="color: #66cc66;">&#40;</span>ldap_util_pipelined<span style="color: #66cc66;">.</span>get_user_groups_nt<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'kvongkas'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
CN
<span style="color: #808080; font-style: italic;">---------------</span>
MONEYBROS_GRP
MONACLE_GRP
SCHMAPPLE_GRP</pre></td></tr></table></div>

<p>All that&#8217;s left for us at this point is to construct a WHERE clause condition to use with Oracle&#8217;s Virtual Private Database feature to limit data returned from queries against the table QUARTERLY_SALES_DATA. That condition could look something like this, assuming that our application connects to the database as the logged in user.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p470code24'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p47024"><td class="code" id="p470code24"><pre class="sql" style="font-family:monospace;">client_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> CASE cn
                       WHEN <span style="color: #ff0000;">'TIMCO_GRP'</span> THEN <span style="color: #cc66cc;">100</span>
                       WHEN <span style="color: #ff0000;">'MONEYBROS_GRP'</span> THEN <span style="color: #cc66cc;">200</span>
                       WHEN <span style="color: #ff0000;">'MONACLE_GRP'</span> THEN <span style="color: #cc66cc;">300</span>
                       WHEN <span style="color: #ff0000;">'SCHMAPPLE_GRP'</span> THEN <span style="color: #cc66cc;">400</span>
                     END
                <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #993333; font-weight: bold;">TABLE</span><span style="color: #66cc66;">&#40;</span>ldap_util_pipelined<span style="color: #66cc66;">.</span>get_user_groups_nt<span style="color: #66cc66;">&#40;</span>USER<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>Here the mapping between AD group name and client ID is hardcoded in the CASE expression. A more flexible way would be to create a mapping table. Also, this is probably not a case study in writing a well performing VPD clause, but the real point here is that using SQL table functions and PL/SQL pipelined functions, we can translate data retrieved from an API, LDAP directory, or web service into table-like structures that we can query, join, and otherwise manipulate just like real tables.</p>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=245406032159496&#038;xfbml=1"></script><br />
<script type="text/javascript" src="//platform.twitter.com/widgets.js"></script><br />
<script type="text/javascript">  (function() {    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;    po.src = 'https://apis.google.com/js/plusone.js';    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);  })();</script><br />
<script src="http://platform.linkedin.com/in.js" type="text/javascript"></script></p>
<div id="fb-root"></div>
<p><fb:like href="" send="false" layout="button_count" width="100" show_faces="false" font="arial"></fb:like><a href="https://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-via="toby_marks">Tweet</a><g:plusone size="medium"></g:plusone><script type="IN/Share" data-url="http://blog.enkitec.com/2011/10/table-functions-9i-feature-worth-revisiting-part-2/" data-counter="right"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2011/10/table-functions-9i-feature-worth-revisiting-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sizing up your environment for backups to tape</title>
		<link>http://blog.enkitec.com/2011/09/sizing-up-your-environment-for-backups-to-tape/</link>
		<comments>http://blog.enkitec.com/2011/09/sizing-up-your-environment-for-backups-to-tape/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 16:11:52 +0000</pubDate>
		<dc:creator>Heath Boral</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Backups]]></category>
		<category><![CDATA[Exadata]]></category>
		<category><![CDATA[Sizing]]></category>
		<category><![CDATA[Tape]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=444</guid>
		<description><![CDATA[So, you just spent many long hours putting together your latest and greatest creation. Hot off the presses, you have a true work of art. Now what? You are being audited on backups? You realize that there was no money for backup gear in the budget, but having this kind of risk over your head [...]]]></description>
			<content:encoded><![CDATA[<p>So, you just spent many long hours putting together your latest and greatest creation. Hot off the presses, you have a true work of art. Now what? You are being audited on backups? You realize that there was no money for backup gear in the budget, but having this kind of risk over your head can only be viewed as something to offload to an over-taxed shared services IT department at your org or a chance to play russian roullette with your data? No! It&#8217;s time to get an accurate assessment of what you need to backup and get your tape requirements sorted out so that you can present a case for your backups and any needed gear to get the job done. Don&#8217;t worry, you may not have to spend 2 trillion dollars on gear (unless you work for the government), especially if you already have a working environment to do your existing backups and just need to find/make capacity on the tape SAN. That being said, you still need to know what you&#8217;ll need to do or ask for and how can you do that if you just go to upper management and say, &#8221; I just got an Exadata and I need at least 48&#215;365 = 17520 TB of capacity in my tape backup gear to make sure we are covered for the year. Let&#8217;s not be greedy. Even the most novice executive will question the costs needed to satisfy that kind of requirement.</p>
<p>Making the assumption that you are using RMAN, you have already configured your backups to run a weekly full on each database to tape once per week, incrementals daily, and a reasonable amount of archivelogs being generated daily to the Fast Recovery Area, we can proceed to estimate your immediate needs.</p>
<p>If you are running Oracle and you are using RMAN, you can get the sizing numbers you need for your tape requirements somewhat easily if you are already taking backups to your Fast Recovery Area. There are a number of different views that can provide information about your backups, but I have found the most beneficial information can be gathered from the views used here. The helpful script that follows can be run to collect data on all the different types of backups you are currently running and the sizes (this script allows you to feed a list of SIDs):</p>
<p>#!/bin/bash</p>
<p>. /home/oracle/.bash_profile</p>
<p>ORAENV_ASK=NO</p>
<p>for DB in `echo &#8220;$DB_LIST&#8221;`; do<br />
export ORACLE_SID=$DB<br />
. oraenv $DB &gt;/dev/null</p>
<p>echo &#8220;Database: $DB&#8221;</p>
<p>sqlplus -s \/ as sysdba&lt;&lt;EOF<br />
set serveroutput on<br />
set linesize 150<br />
set pagesize 300</p>
<p>select ctime &#8220;Date&#8221;,</p>
<p>decode(backup_type, &#8216;L&#8217;, &#8216;Archive Log&#8217;, &#8216;D&#8217;, &#8216;Full&#8217;, &#8216;Incremental&#8217;) backup_type,bsize &#8220;Size GB&#8221; from (select trunc(bp.completion_time) ctime, backup_type, round(sum(bp.bytes/1024/1024/1024),2) bsize</p>
<p>from v\$backup_set bs,</p>
<p>v\$backup_piece bp where bs.set_stamp = bp.set_stamp and bs.set_count  = bp.set_count and bp.status = &#8216;A&#8217; group by trunc(bp.completion_time), backup_type) order by 1, 2;</p>
<p>exit;<br />
EOF<br />
done</p>
<p>You can then look at the history of your current backups and right-size your tape requirements.</p>
<p>You might also check how many archive logs you are generating in a week under full production load:</p>
<p>&nbsp;</p>
<p>col gbytes form 999,999.99</p>
<p>select sum(blocks*block_size)/1024/1024/1024 gbytes</p>
<p>from v$archived_log</p>
<p>where next_time &gt; sysdate-8;</p>
<p>&nbsp;</p>
<p>Some things to consider when you decide on your tape solution:</p>
<p>The type of tape drives</p>
<p>Encryption needs</p>
<p>The amount of compression</p>
<p>The number of tape drives</p>
<p>The type of backup software (OSB vs Netbackup vs Tivoli)</p>
<p>Your vaulting schedule (number of available media slots)</p>
<p>How fast can your channel send the data to the tape drives</p>
<p>Assuming you already have a tape SAN and you are not given enough money in your budget or enough lead time to get the gear in place before an audit, you might consider looking at what you have now in place and checking to see if you are doing too many backups, you have tuned your backups incorrectly, or if you have a number of backups that would benefit from VTL or dedup technologies in order to free space on your existing tape infrastructure.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2011/09/sizing-up-your-environment-for-backups-to-tape/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Get Oracle Instant Client Working on Mac OS X Lion</title>
		<link>http://blog.enkitec.com/2011/08/get-oracle-instant-client-working-on-mac-os-x-lion/</link>
		<comments>http://blog.enkitec.com/2011/08/get-oracle-instant-client-working-on-mac-os-x-lion/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 14:46:21 +0000</pubDate>
		<dc:creator>Toby Marks</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[10.7]]></category>
		<category><![CDATA[hints]]></category>
		<category><![CDATA[Lion]]></category>
		<category><![CDATA[Oracle Instant Client]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[rlwrap]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=420</guid>
		<description><![CDATA[CJ Travis has an excellent and thorough article on installing Oracle Instant Client on Mac OS X 10.7. The gist: you have to install the 32-bit version. As a bonus, he tells you how to download and install the handy rlwrap command line utility, which gives you the ability to navigate the statement history in [...]]]></description>
			<content:encoded><![CDATA[<p>CJ Travis has an <a href="http://www.cjtravis.com/?p=744">excellent and thorough article</a> on installing Oracle Instant Client on Mac OS X 10.7. The gist: you have to install the 32-bit version. As a bonus, he tells you how to download and install the handy <a href="http://blog.enkitec.com/2010/04/using-sqlplus-with-rlwrap-on-ms-windows/">rlwrap</a> command line utility, which gives you the ability to navigate the statement history in SQL*Plus in a very bash-like fashion, using the up and down keys.</p>
<p><span id="more-420"></span></p>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=245406032159496&#038;xfbml=1"></script><br />
<script type="text/javascript" src="//platform.twitter.com/widgets.js"></script><br />
<script type="text/javascript">  (function() {    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;    po.src = 'https://apis.google.com/js/plusone.js';    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);  })();</script><br />
<script src="http://platform.linkedin.com/in.js" type="text/javascript"></script>
<div id="fb-root"></div>
<p><fb:like href="" send="false" layout="button_count" width="100" show_faces="false" font="arial"></fb:like><a href="https://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-via="toby_marks">Tweet</a><g:plusone size="medium"></g:plusone><script type="IN/Share" data-url="http://blog.enkitec.com/2011/08/get-oracle-instant-client-working-on-mac-os-x-lion/" data-counter="right"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2011/08/get-oracle-instant-client-working-on-mac-os-x-lion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Table Functions: 9i Feature Worth Revisiting (Part 1)</title>
		<link>http://blog.enkitec.com/2011/08/table-functions-9i-feature-worth-revisiting-part-1/</link>
		<comments>http://blog.enkitec.com/2011/08/table-functions-9i-feature-worth-revisiting-part-1/#comments</comments>
		<pubDate>Fri, 12 Aug 2011 17:48:49 +0000</pubDate>
		<dc:creator>Toby Marks</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[9i]]></category>
		<category><![CDATA[PIPE ROW]]></category>
		<category><![CDATA[PIPELINED]]></category>
		<category><![CDATA[TABLE]]></category>
		<category><![CDATA[Table Functions]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=407</guid>
		<description><![CDATA[Yes, they&#8217;ve been around for a while, but if you haven&#8217;t made use of table functions lately you might want to reacquaint yourself with this old gem. Table functions allow you to query the contents of PL/SQL collection types using SQL&#8217;s TABLE operator. Here is a simple example. ?View Code SQLCREATE OR REPLACE PACKAGE example [...]]]></description>
			<content:encoded><![CDATA[<p>Yes, they&#8217;ve been around for a while, but if you haven&#8217;t made use of table functions lately you might want to reacquaint yourself with this old gem. Table functions allow you to query the contents of PL/SQL collection types using SQL&#8217;s TABLE operator. Here is a simple example.</p>
<p><span id="more-407"></span></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code28'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40728"><td class="code" id="p407code28"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> PACKAGE example <span style="color: #993333; font-weight: bold;">AS</span>
&nbsp;
     TYPE nested_table_typ <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">TABLE</span> OF VARCHAR2<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
     <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_nested_table_data <span style="color: #993333; font-weight: bold;">RETURN</span> nested_table_typ PIPELINED;
&nbsp;
END example;
<span style="color: #66cc66;">/</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> PACKAGE BODY example <span style="color: #993333; font-weight: bold;">AS</span>
&nbsp;
     <span style="color: #993333; font-weight: bold;">FUNCTION</span> get_nested_table_data <span style="color: #993333; font-weight: bold;">RETURN</span> nested_table_typ PIPELINED <span style="color: #993333; font-weight: bold;">IS</span>
     BEGIN
          PIPE ROW <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'one'</span><span style="color: #66cc66;">&#41;</span>;
          PIPE ROW <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'two'</span><span style="color: #66cc66;">&#41;</span>;
          PIPE ROW <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'three'</span><span style="color: #66cc66;">&#41;</span>;
          <span style="color: #993333; font-weight: bold;">RETURN</span>;
     END get_nested_table_data;
&nbsp;
END example;
<span style="color: #66cc66;">/</span></pre></td></tr></table></div>

<p>The package function example.get_nested_table_data returns a PL/SQL collection — in this case, a nested table. The PIPELINED directive instructs the function to return data to the calling query as rows are populated by the PIPE ROW command. That way, you don&#8217;t need to wait for the function to finish before you get results from your query.</p>
<p>The function can be invoked from the SELECT clause of a query in the usual way, and will return a valid result.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code29'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40729"><td class="code" id="p407code29"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> example<span style="color: #66cc66;">.</span>get_nested_table_data <span style="color: #993333; font-weight: bold;">FROM</span> dual;
&nbsp;
GET_NESTED_TABLE_DATA
<span style="color: #808080; font-style: italic;">-------------------------------</span>
SCHEMA<span style="color: #66cc66;">.</span>SYS_PLSQL_166672_9_1<span style="color: #66cc66;">&#40;</span>one<span style="color: #66cc66;">,</span>two<span style="color: #66cc66;">,</span>three<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>This is possible because nested tables and VARRAYs are supported as native types in SQL. The other type of PL/SQL collection, associative arrays, are not. Therefore you cannot use an associative array as the return type of a pipelined table function. However, it&#8217;s pretty trivial to create a wrapper function that translates an associative array into a nested table. You wouldn&#8217;t necessarily take this approach in your own code, but it comes in handy when you&#8217;re transforming data coming from a third party package or function.</p>
<p>But what if you need the contents of the collection presented as a table, with one record per entry in the collection? This is where the TABLE operator comes in handy.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p407code30'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p40730"><td class="code" id="p407code30"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> column_value <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #993333; font-weight: bold;">TABLE</span><span style="color: #66cc66;">&#40;</span>example<span style="color: #66cc66;">.</span>get_nested_table_data<span style="color: #66cc66;">&#41;</span>;
&nbsp;
COLUMN_VALUE
<span style="color: #808080; font-style: italic;">-------------------</span>
one
two
three</pre></td></tr></table></div>

<p>The TABLE operator casts a collection type as an aggregated result set, meaning it allows you to query it as if it were a table.</p>
<p>Why would you need to do this?</p>
<p>One reason might be because you want to query or join data retrieved from a web service, or from an LDAP server. Another reason might be to simplify a complex query with lots of unions, case statements, and subqueries by fetching, manipulating, and combining your data inside a PL/SQL function. You can leverage the ease and maintainability of building your collection in a procedural manner, while still having access to the collection data from SQL. There is some overhead associated with that approach, though, so you&#8217;ll want to be careful about applying it in performance-critical situations. Still, though, it&#8217;s worth considering when the complexity of SQL constructs gets out of hand.</p>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=245406032159496&#038;xfbml=1"></script><br />
<script type="text/javascript" src="//platform.twitter.com/widgets.js"></script><br />
<script type="text/javascript">  (function() {    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;    po.src = 'https://apis.google.com/js/plusone.js';    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);  })();</script><br />
<script src="http://platform.linkedin.com/in.js" type="text/javascript"></script>
<div id="fb-root"></div>
<p><fb:like href="" send="false" layout="button_count" width="100" show_faces="false" font="arial"></fb:like><a href="https://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-via="toby_marks">Tweet</a><g:plusone size="medium"></g:plusone><script type="IN/Share" data-url="http://blog.enkitec.com/?p=407" data-counter="right"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2011/08/table-functions-9i-feature-worth-revisiting-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recyclebin</title>
		<link>http://blog.enkitec.com/2011/05/recyclebin/</link>
		<comments>http://blog.enkitec.com/2011/05/recyclebin/#comments</comments>
		<pubDate>Wed, 25 May 2011 10:48:23 +0000</pubDate>
		<dc:creator>Jon Adams</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=357</guid>
		<description><![CDATA[What is the recyclebin? The Oracle recyclebin has been around since version 10g release 1 as part of a feature called Flashback Drop and in my opinion, continues to be a little-known and little-understood feature. It has saved me from potential data loss on at least one occasion, though, so I think it deserves some [...]]]></description>
			<content:encoded><![CDATA[<p>What is the recyclebin?<br />
The Oracle recyclebin has been around since version 10g release 1 as part of a feature called Flashback Drop and in my opinion, continues to be a little-known and little-understood feature.  It has saved me from potential data loss on at least one occasion, though, so I think it deserves some consideration.<br />
The recyclebin is actually a data dictionary table containing information about dropped objects. Each named user account has their own recyclebin.  Unless a user has the SYSDBA privilege, the only objects that the user has access to in the recyclebin are those that the user owns. A user can view his objects in the recyclebin using the following statement:</p>
<p><span id="more-357"></span></p>
<p>SELECT * FROM RECYCLEBIN;</p>
<p>Dropped tables and any associated objects such as indexes, constraints, nested tables, are not removed when the table is dropped and still occupy space in the tablespace where they originated.  They continue to count against user space quotas, until specifically purged from the recyclebin either manually or by the database because of tablespace space constraints.</p>
<p>When you drop a tablespace including its contents, the objects in the tablespace are NOT placed in the recycle bin AND the database purges any entries in the recycle bin for objects located in that tablespace.</p>
<p>When you drop a user, any objects belonging to the user are not placed in the recycle bin and any objects in the recycle bin are purged that belong to that user.</p>
<p>When you drop a cluster, its member tables are not placed in the recycle bin and any former member tables in the recycle bin are purged that belong to that cluster.</p>
<p>When you drop a type, any dependent objects such as subtypes are not placed in the recycle bin and any former dependent objects in the recycle bin are purged.</p>
<p>Recyclebin Settings<br />
In 10g release 1, recyclebin was enabled by default and there was only an undocumented parameter to disable it.  This parameter was _recyclebin which defaulted to a value of TRUE.  The recyclebin initialization parameter was introduced in 10g release 2 and had a default setting of ‘on’.  It was a dynamic parameter and could be enabled or disabled with either an ‘alter session’ or an ‘alter system’ command.  Oracle 11g release 1 made no changes to the basic feature, except to add the ‘deferred’ option to the ‘alter session’ command to allow subsequent, but not the current, session to be affected.  Release 2 remained unchanged from release 1.<br />
To find out if the recyclebin is enabled, except for 10g release 1, you can execute ‘show parameter recyclebin’ from a SQL prompt as a user with sysdba privileges.<br />
Sample output:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p357code34'); return false;">View Code</a> NONE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p35734"><td class="code" id="p357code34"><pre class="none" style="font-family:monospace;">SQL&amp;gt; show parameter recyclebin
&nbsp;
NAME                                 TYPE                             VALUE
------------------------------------ -------------------------------- ------------------------------
recyclebin                           string                           on</pre></td></tr></table></div>

<p>I would recommend keeping the recyclebin enabled at all times, except during an upgrade, to add an extra layer of recovery options to the existing environment.</p>
<p>Using Recyclebin</p>
<p>Once recyclebin is enabled, you don’t have to give much thought to its use.  Every time a ‘drop table’ command is executed, the table and its associated objects (indexes, constraints, nested tables) are placed in the recyclebin and renamed with a system-generated naming standard.  Because objects age out of the recyclebin based on demands for space, it is always a good idea to back up a table with an export or a create table as select (CTAS) option before dropping it.  This is especially true for dropping very large tables which may not fit in the recyclebin.</p>
<p>In the event that you do not want a table to be preserved in the recyclebin, the addition of the ‘purge’ option at the end of the ‘drop table’ statement ensures that the recyclebin bin is bypassed and the table as well as the associated objects are dropped from the database.</p>
<p>Purging the recyclebin can be performed at both the user and system level.  As stated earlier, each named account in the database will automatically have a recyclebin  assigned to it.  A user can simply execute the ‘purge recyclebin’ command to purge their individual recyclebin.  Users with the sysdba privilege can purse the entire recyclebin with the ‘purge dba_recyclebin’ command.  Be careful, though, as this command also purges the users’ individual recyclebins as well.  Purging the entire reyclebin should be reserved for upgrade situations, or unless otherwise directed by Oracle Support.</p>
<p>You can also perform selective purges of the recyclebin.  For example ‘purge tablespace tmpdata’ only purges those objects in the recyclebin belonging to the tmpdata tablespace.  Also, ‘purge tablespace tmpdata user jon’ will purge only those objects in the recyclebin belonging to the tmpdata tablespace owned by the named user jon.  You can also purge individual tables from the recyclebin with the command ‘purge table<br />
’.  The table name in this command can be either the system-generated recyclebin name or the original name of the table.</p>
<p>To recover a table from the recyclebin, you need to know if it is available.  Use the following query to get this information:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p357code35'); return false;">View Code</a> NONE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p35735"><td class="code" id="p357code35"><pre class="none" style="font-family:monospace;">select owner, object_name, original_name, droptime
from dba_recyclebin
where owner = ‘CMN’;
&nbsp;
OWNER                          OBJECT_NAME                    ORIGINAL_NAME                    DROPTIME
------------------------------ ------------------------------ -------------------------------- -------------------
CMN                            BIN$o5lg4yWjH3ngRAAUT0rhuQ==$0 CMN_BASE_CONTACT                 2011-05-18:23:12:42
CMN                            BIN$o5lg4yWiH3ngRAAUT0rhuQ==$0 CMN_BASE_CONTACT_PK              2011-05-18:23:12:42
CMN                            BIN$o5icV6rtByXgRAAUT0rhuQ==$0 CMN_BASE_CONTACT                 2011-05-18:22:51:07
CMN                            BIN$o5icV6rfByXgRAAUT0rhuQ==$0 CMN_BASE_CONTACT                 2011-05-18:22:17:45
CMN                            BIN$o5lg4yWvH3ngRAAUT0rhuQ==$0 CMN_BASE_CONTACT                 2011-05-18:23:15:11
CMN                            BIN$o5icV6rgByXgRAAUT0rhuQ==$0 EXECUTE_TABLE                    2011-05-18:22:49:58
CMN                            BIN$o5mU5fo6KF/gRAAUT0rhuQ==$0 EXECUTE_TABLE                    2011-05-18:23:30:15
CMN                            BIN$o5icV6ruByXgRAAUT0rhuQ==$0 EXECUTE_TABLE                    2011-05-18:22:53:23
CMN                            BIN$o5mU5foqKF/gRAAUT0rhuQ==$0 CMN_BASE_CONTACT                 2011-05-18:23:27:15
CMN                            BIN$o5mU5fo5KF/gRAAUT0rhuQ==$0 CMN_BASE_CONTACT                 2011-05-18:23:30:08
CMN                            BIN$o5mU5fo4KF/gRAAUT0rhuQ==$0 CMN_BASE_CONTACT_PK              2011-05-18:23:30:08
CMN                            BIN$o5mU5fpGKF/gRAAUT0rhuQ==$0 CMN_BASE_CONTACT                 2011-05-18:23:32:02
CMN                            BIN$o5mU5fpHKF/gRAAUT0rhuQ==$0 EXECUTE_TABLE                    2011-05-18:23:32:02</pre></td></tr></table></div>

<p>NOTE – The owner clause in this query was only given to limit the size of the output.</p>
<p>From this output, you can see which tables are present in the recyclebin and when they were dropped.  As you can see, there can be several versions of the same table in the recyclebin.</p>
<p>This brings us to the purpose of the recyclebin – recovering an accidentally dropped table.  What you may or may not know is that the recyclebin tables can be queried like normal tables.  You can query the recyclebin copies of the table until you find the one that contains the data you are interested in…</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p357code36'); return false;">View Code</a> NONE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p35736"><td class="code" id="p357code36"><pre class="none" style="font-family:monospace;">select count(*)
from cmn.&quot;BIN$o5mU5fpGKF/gRAAUT0rhuQ==$0&quot;;
&nbsp;
  COUNT(*)
----------
        89</pre></td></tr></table></div>

<p>Note that it is important to use both the owner identifier (CMN) and double-quotation marks because of the special characters in the recyclebin table name.<br />
Once the table you want to recover has been identified, there are a few different methods by which you can recover the table or the individual data.  The ‘flashback table<br />
to before drop’ command will recover the latest copy of the table in the recyclebin.  You can also specify the ‘rename to ’ at the end of the command to recover the table to a different table name.  In the case where there are several copies of the table in the recyclebin and you are not interested in the latest copy, you can do a simple create table as select (CTAS) operation using the recyclebin table name, not the original name.  Remember to use double-quotation marks around the recyclebin table name due to the special characters.  You should also be able to recover select rows from the recyclebin table using the same method.</p>
<p>Summary<br />
In situations where the code we deploy is beyond our control, this feature may prove invaluable.  It is one of those features that you can set and forget, but are very thankful when it is available and you need it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2011/05/recyclebin/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Make bash scripts crontab-compatible</title>
		<link>http://blog.enkitec.com/2011/05/make-bash-scripts-crontab-compatible/</link>
		<comments>http://blog.enkitec.com/2011/05/make-bash-scripts-crontab-compatible/#comments</comments>
		<pubDate>Fri, 06 May 2011 17:05:08 +0000</pubDate>
		<dc:creator>Toby Marks</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[crontab]]></category>
		<category><![CDATA[hints]]></category>
		<category><![CDATA[shell scripting]]></category>

		<guid isPermaLink="false">http://blog.enkitec.com/?p=315</guid>
		<description><![CDATA[When writing shell scripts in bash, consider whether your script can be automated in a batch scheduler like cron. If you reference any external resources in your script relative to the directory in which it resides, those references may break when running your script through cron. By default, crontab runs scripts in the user&#8217;s home [...]]]></description>
			<content:encoded><![CDATA[<p>When writing shell scripts in bash, consider whether your script can be automated in a batch scheduler like cron. If you reference any external resources in your script relative to the directory in which it resides, those references may break when running your script through cron.</p>
<p>By default, crontab runs scripts in the user&#8217;s home directory, as specified in <em>/etc/passwd</em>. For user &#8220;Tim&#8221; with home directory <em>/home/tim</em>, a sample crontab might look something like the following:</p>
<p><span id="more-315"></span></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p315code42'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p31542"><td class="code" id="p315code42"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">0</span> <span style="color: #000000;">0</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> runme.sh</pre></td></tr></table></div>

<p>Every night at midnight, cron will try to run the file <em>/home/tim/runme.sh</em>. However, if <em>runme.sh</em> is actually in a sub-directory under <em>~tim</em>, you will need to tell cron how to reach the file. One option would be to qualify the path in crontab, like so:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p315code43'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p31543"><td class="code" id="p315code43"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">0</span> <span style="color: #000000;">0</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> ~<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>runme.sh</pre></td></tr></table></div>

<p>Now cron can find the file. However, if the script makes references to other files inside of <em>/bin</em> in a path-relative way, those references will be broken.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p315code44'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p31544"><td class="code" id="p315code44"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;">#runme.sh</span>
.<span style="color: #000000; font-weight: bold;">/</span>runthis.sh      <span style="color: #666666; font-style: italic;"># can't find this file when running under cron</span>
.<span style="color: #000000; font-weight: bold;">/</span>runthat.sh      <span style="color: #666666; font-style: italic;"># can't find this file when running under cron</span></pre></td></tr></table></div>

<p>That&#8217;s because to cron <em>./</em> is not the directory in which the script is running, but rather whatever is defined as the base directory; in the default case, the user&#8217;s home directory.</p>
<p>It is possible to specify the base directory in the crontab file itself by defining the special variable <em>HOME</em>.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p315code45'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p31545"><td class="code" id="p315code45"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">HOME</span>=<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>tim<span style="color: #000000; font-weight: bold;">/</span>bin
<span style="color: #000000;">0</span> <span style="color: #000000;">0</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span> runme.sh</pre></td></tr></table></div>

<p>However, you may not always have control over how your crontab is configured. Perhaps a system administrator is in charge of all the schedules on your server. Or you may organize your scripts in several different directories.</p>
<p>An easy solution is to start your bash scripts with the following command:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p315code46'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p31546"><td class="code" id="p315code46"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #007800;">$0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></td></tr></table></div>

<p>The program <em>dirname</em> returns the directory portion of the fully qualified path name sent to it. The <em>$0</em> argument in this context is name of the running script. Basically, this code ensures that the current working directory is the same as the directory in which your script is running. That way all your path-relative references are correct whether running manually or through a scheduler.</p>
<p><script src="http://connect.facebook.net/en_US/all.js#appId=245406032159496&#038;xfbml=1"></script><br />
<script type="text/javascript" src="//platform.twitter.com/widgets.js"></script><br />
<script type="text/javascript">  (function() {    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;    po.src = 'https://apis.google.com/js/plusone.js';    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);  })();</script><br />
<script src="http://platform.linkedin.com/in.js" type="text/javascript"></script>
<div id="fb-root"></div>
<p><fb:like href="" send="false" layout="button_count" width="100" show_faces="false" font="arial"></fb:like><a href="https://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-via="toby_marks">Tweet</a><g:plusone size="medium"></g:plusone><script type="IN/Share" data-url="http://blog.enkitec.com/?p=315" data-counter="right"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.enkitec.com/2011/05/make-bash-scripts-crontab-compatible/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

