<?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>MacLochlainns Weblog &#187; associative array</title>
	<atom:link href="http://blog.mclaughlinsoftware.com/tag/associative-array/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mclaughlinsoftware.com</link>
	<description>Michael McLaughlin's Technical Blog</description>
	<lastBuildDate>Mon, 06 Sep 2010 21:21:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Result cache functions disallow nested table input parameters</title>
		<link>http://blog.mclaughlinsoftware.com/2008/05/25/result-cache-functions-disallow-nested-table-input-parameters/</link>
		<comments>http://blog.mclaughlinsoftware.com/2008/05/25/result-cache-functions-disallow-nested-table-input-parameters/#comments</comments>
		<pubDate>Sun, 25 May 2008 23:15:09 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[associative array]]></category>
		<category><![CDATA[collection]]></category>
		<category><![CDATA[nested table]]></category>
		<category><![CDATA[PLS-00999]]></category>
		<category><![CDATA[result_cache]]></category>

		<guid isPermaLink="false">http://maclochlainn.wordpress.com/?p=24</guid>
		<description><![CDATA[If you implement street address as a nested table (or collection), the problem is printing an address book using only a SQL statement. The problem comes from matching up the multiple line return from the TABLE function with the rest of the row. That’s not a problem when you denormalized the list into known columns. [...]]]></description>
			<content:encoded><![CDATA[<p>If you implement street address as a nested table (or collection), the problem is printing an address book using only a SQL statement. The problem comes from matching up the multiple line return from the <code>TABLE</code> function with the rest of the row. That’s not a problem when you denormalized the list into known columns.</p>
<p>A PL/SQL function can convert the list into a scalar value. It&#8217;s an easy way to leverage a nested table. You can find the full code <a title="How to Join nested tables with their containing row" href="http://blog.mclaughlinsoftware.com/nested-tables-and-how-to-join-them-to-their-containing-rows/" target="_blank">here</a>. You might think that this is a neat opportunity to use a result cache function. I did, but the behavior isn’t presently supported. On compilation of a function with the <code>RESULT_CACHE</code> clause and a scalar collection input parameter, you raise a <code>PLS-00999</code> error.</p>
<p>The message tells you:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">RESULT_CACHE <span style="color: #993333; font-weight: bold;">IS</span> disallowed <span style="color: #993333; font-weight: bold;">ON</span> subprograms <span style="color: #993333; font-weight: bold;">WITH</span> <span style="color: #993333; font-weight: bold;">IN</span> parameter of <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">OR</span> containing<span style="color: #66cc66;">&#41;</span> nested <span style="color: #993333; font-weight: bold;">TABLE</span> type</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2008/05/25/result-cache-functions-disallow-nested-table-input-parameters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reversing direction in a PL/SQL range for-loop</title>
		<link>http://blog.mclaughlinsoftware.com/2008/05/21/reversing-direction-in-a-plsql-range-for-loop/</link>
		<comments>http://blog.mclaughlinsoftware.com/2008/05/21/reversing-direction-in-a-plsql-range-for-loop/#comments</comments>
		<pubDate>Wed, 21 May 2008 04:29:27 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[associative array]]></category>
		<category><![CDATA[character index]]></category>
		<category><![CDATA[collection]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[reversing loop]]></category>

		<guid isPermaLink="false">http://maclochlainn.wordpress.com/?p=20</guid>
		<description><![CDATA[Have you ever wondered how to decrement index values in a PL/SQL range for-loop. You’ve probably heard that you can’t. That’s part true and part false. The true part is two fold. First, range for-loops move forward from a starting low value to high value. Second, the loop exits immediately when your starting value is [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered how to decrement index values in a PL/SQL range for-loop. You’ve probably heard that you can’t. That’s part true and part false.</p>
<p>The true part is two fold. First, range for-loops move forward from a starting low value to high value. Second, the loop exits immediately when your starting value is high and ending value low. If you use the <code>REVERSE</code> keyword, the loop moves backward from an ending point to the starting point. This happens because a PL/SQL range for-loop is a guard on entry loop. The starting value is compared against the ending value and exits when the starting value is greater than the ending value.</p>
<p>The false part happens when you want to traverse a collection backward. Oracle collections are varrays, tables, or associative arrays. Associative arrays are also known as PL/SQL tables. You overcome the <em>ascending only</em> limitation by using the <code>REVERSE</code> keyword or leveraging the Oracle Collection API library functions.</p>
<p>This code works when the index is numeric:</p>

<div class="wp_syntax"><div class="code"><pre class="plsql" style="font-family:monospace;"><span style="color: #00F;">DECLARE</span>
  <span style="color: #00F;">TYPE</span> collection <span style="color: #00F;">IS</span> <span style="color: #00F;">TABLE</span> <span style="color: #00F;">OF</span> <span style="color: #00F;">VARCHAR2</span><span style="color: #00F;">&#40;</span><span style="color: #800;">20</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
  fellowship COLLECTION <span style="color: #00F;">:=</span> collection<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Frodo'</span><span style="color: #00F;">,</span><span style="color: #F00;">'Gandalf'</span><span style="color: #00F;">,</span><span style="color: #F00;">'Aragorn'</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
<span style="color: #00F;">BEGIN</span>
  <span style="color: #080; font-style: italic;">-- Increasing iterator values.</span>
  <span style="color: #00F;">FOR</span> i <span style="color: #00F;">IN</span> <span style="color: #00F;">REVERSE</span> 1<span style="color: #00F;">..</span>fellowship<span style="color: #00F;">.</span><span style="color: #000;">COUNT</span> <span style="color: #00F;">LOOP</span>
    <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>put<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Iterator ['</span><span style="color: #00F;">||</span>i<span style="color: #00F;">||</span><span style="color: #F00;">'] '</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>put<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Value ['</span><span style="color: #00F;">||</span>fellowship<span style="color: #00F;">&#40;</span>i<span style="color: #00F;">&#41;</span><span style="color: #00F;">||</span><span style="color: #F00;">']'</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>new_line<span style="color: #00F;">&#40;</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
  <span style="color: #00F;">END</span> <span style="color: #00F;">LOOP</span><span style="color: #00F;">;</span>
<span style="color: #00F;">END</span><span style="color: #00F;">;</span>
<span style="color: #00F;">/</span></pre></div></div>

<p>This code works when the index is a string in an associative array:</p>

<div class="wp_syntax"><div class="code"><pre class="plsql" style="font-family:monospace;"><span style="color: #00F;">DECLARE</span>
  <span style="color: #00F;">CURRENT</span> <span style="color: #00F;">VARCHAR2</span><span style="color: #00F;">&#40;</span><span style="color: #800;">8</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
  element <span style="color: #00F;">VARCHAR2</span><span style="color: #00F;">&#40;</span><span style="color: #800;">20</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
  <span style="color: #00F;">TYPE</span> collection <span style="color: #00F;">IS</span> <span style="color: #00F;">TABLE</span> <span style="color: #00F;">OF</span> <span style="color: #00F;">VARCHAR2</span><span style="color: #00F;">&#40;</span><span style="color: #800;">20</span><span style="color: #00F;">&#41;</span>
    <span style="color: #00F;">INDEX</span> <span style="color: #00F;">BY</span> <span style="color: #00F;">VARCHAR2</span><span style="color: #00F;">&#40;</span><span style="color: #800;">8</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
  fellowship COLLECTION<span style="color: #00F;">;</span>
<span style="color: #00F;">BEGIN</span>
  <span style="color: #080; font-style: italic;">-- Assign character indexed values.</span>
  fellowship<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Hobbit'</span><span style="color: #00F;">&#41;</span> <span style="color: #00F;">:=</span> <span style="color: #F00;">'Frodo'</span><span style="color: #00F;">;</span>
  fellowship<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Wizard'</span><span style="color: #00F;">&#41;</span> <span style="color: #00F;">:=</span> <span style="color: #F00;">'Gandalf'</span><span style="color: #00F;">;</span>
  fellowship<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Human'</span><span style="color: #00F;">&#41;</span>  <span style="color: #00F;">:=</span> <span style="color: #F00;">'Aragorn'</span><span style="color: #00F;">;</span>
  <span style="color: #080; font-style: italic;">-- Increasing iterator values.</span>
  <span style="color: #00F;">FOR</span> i <span style="color: #00F;">IN</span> 1<span style="color: #00F;">..</span>fellowship<span style="color: #00F;">.</span><span style="color: #000;">COUNT</span> <span style="color: #00F;">LOOP</span>
    <span style="color: #00F;">IF</span> i <span style="color: #00F;">=</span> <span style="color: #800;">1</span> <span style="color: #00F;">THEN</span> <span style="color: #080; font-style: italic;">-- Set starting point and assign value.</span>
      <span style="color: #00F;">CURRENT</span> <span style="color: #00F;">:=</span> fellowship<span style="color: #00F;">.</span><span style="color: #000;">LAST</span><span style="color: #00F;">;</span>
      element <span style="color: #00F;">:=</span> fellowship<span style="color: #00F;">&#40;</span><span style="color: #00F;">CURRENT</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">ELSE</span> <span style="color: #080; font-style: italic;">-- Change value until you read the first element.</span>
      <span style="color: #00F;">IF</span> fellowship<span style="color: #00F;">.</span><span style="color: #00F;">PRIOR</span><span style="color: #00F;">&#40;</span><span style="color: #00F;">CURRENT</span><span style="color: #00F;">&#41;</span> <span style="color: #00F;">IS</span> <span style="color: #00F;">NOT</span> <span style="color: #00F;">NULL</span> <span style="color: #00F;">THEN</span>
        <span style="color: #00F;">CURRENT</span> <span style="color: #00F;">:=</span> fellowship<span style="color: #00F;">.</span><span style="color: #00F;">PRIOR</span><span style="color: #00F;">&#40;</span><span style="color: #00F;">CURRENT</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
        element <span style="color: #00F;">:=</span> fellowship<span style="color: #00F;">&#40;</span><span style="color: #00F;">CURRENT</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
      <span style="color: #00F;">ELSE</span> <span style="color: #080; font-style: italic;">-- Exit when all elements read.</span>
        <span style="color: #00F;">EXIT</span><span style="color: #00F;">;</span>
      <span style="color: #00F;">END</span> <span style="color: #00F;">IF</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">END</span> <span style="color: #00F;">IF</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>put<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Iterator ['</span><span style="color: #00F;">||</span>i<span style="color: #00F;">||</span><span style="color: #F00;">'] '</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>put<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Index ['</span><span style="color: #00F;">||</span>current<span style="color: #00F;">||</span><span style="color: #F00;">'] '</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>put<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Value ['</span><span style="color: #00F;">||</span>element<span style="color: #00F;">||</span><span style="color: #F00;">']'</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>new_line<span style="color: #00F;">&#40;</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
  <span style="color: #00F;">END</span> <span style="color: #00F;">LOOP</span><span style="color: #00F;">;</span>
<span style="color: #00F;">END</span><span style="color: #00F;">;</span>
<span style="color: #00F;">/</span></pre></div></div>

<p>Chris Neumüller suggested another example with a <code>WHILE</code> loop:</p>

<div class="wp_syntax"><div class="code"><pre class="plsql" style="font-family:monospace;"><span style="color: #00F;">DECLARE</span>
  <span style="color: #00F;">TYPE</span> collection <span style="color: #00F;">IS</span> <span style="color: #00F;">TABLE</span> <span style="color: #00F;">OF</span> <span style="color: #00F;">VARCHAR2</span><span style="color: #00F;">&#40;</span><span style="color: #800;">20</span><span style="color: #00F;">&#41;</span> <span style="color: #00F;">INDEX</span> <span style="color: #00F;">BY</span> <span style="color: #00F;">VARCHAR2</span><span style="color: #00F;">&#40;</span><span style="color: #800;">8</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
  fellowship COLLECTION<span style="color: #00F;">;</span>
  <span style="color: #00F;">CURRENT</span>    <span style="color: #00F;">VARCHAR2</span><span style="color: #00F;">&#40;</span><span style="color: #800;">20</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
<span style="color: #00F;">BEGIN</span>
  <span style="color: #080; font-style: italic;">-- Assign character indexed values.</span>
  fellowship<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Hobbit'</span><span style="color: #00F;">&#41;</span> <span style="color: #00F;">:=</span> <span style="color: #F00;">'Frodo'</span><span style="color: #00F;">;</span>
  fellowship<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Wizard'</span><span style="color: #00F;">&#41;</span> <span style="color: #00F;">:=</span> <span style="color: #F00;">'Gandalf'</span><span style="color: #00F;">;</span>
  fellowship<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Human'</span><span style="color: #00F;">&#41;</span>  <span style="color: #00F;">:=</span> <span style="color: #F00;">'Aragorn'</span><span style="color: #00F;">;</span>
  <span style="color: #080; font-style: italic;">-- Increasing iterator values.</span>
  <span style="color: #00F;">IF</span> fellowship<span style="color: #00F;">.</span><span style="color: #000;">COUNT</span> <span style="color: #00F;">&gt;</span> <span style="color: #800;">0</span> <span style="color: #00F;">THEN</span>
    <span style="color: #00F;">CURRENT</span> <span style="color: #00F;">:=</span> fellowship<span style="color: #00F;">.</span><span style="color: #000;">LAST</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">WHILE</span> <span style="color: #00F;">CURRENT</span> <span style="color: #00F;">IS</span> <span style="color: #00F;">NOT</span> <span style="color: #00F;">NULL</span> <span style="color: #00F;">LOOP</span>
      <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>put<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Iterator ['</span><span style="color: #00F;">||</span>current<span style="color: #00F;">||</span><span style="color: #F00;">'] '</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
      <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>put<span style="color: #00F;">&#40;</span><span style="color: #F00;">'Value ['</span><span style="color: #00F;">||</span>fellowship<span style="color: #00F;">&#40;</span><span style="color: #00F;">CURRENT</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">||</span><span style="color: #F00;">'] '</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
      <span style="color: #00F;">DBMS_OUTPUT</span><span style="color: #00F;">.</span>new_line<span style="color: #00F;">&#40;</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
      <span style="color: #00F;">CURRENT</span> <span style="color: #00F;">:=</span> fellowship<span style="color: #00F;">.</span><span style="color: #00F;">PRIOR</span><span style="color: #00F;">&#40;</span><span style="color: #00F;">CURRENT</span><span style="color: #00F;">&#41;</span><span style="color: #00F;">;</span>
    <span style="color: #00F;">END</span> <span style="color: #00F;">LOOP</span><span style="color: #00F;">;</span>
  <span style="color: #00F;">END</span> <span style="color: #00F;">IF</span><span style="color: #00F;">;</span>
<span style="color: #00F;">END</span><span style="color: #00F;">;</span>
<span style="color: #00F;">/</span></pre></div></div>

<p>While the former works, you should consider changing the cursor that populates the collection by adding a descending <code>ORDER BY</code> clause when indexing with a string. The algorithm is a bit more work but it also supports sparsely populated indexes and string-indexed associative arrays. All you need do is swap the <code>LAST</code> for <code>FIRST</code> and <code>PRIOR</code> for <code>NEXT</code> to go forward through a sparsely populated index.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2008/05/21/reversing-direction-in-a-plsql-range-for-loop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
