{"id":7760,"date":"2021-05-04T23:11:58","date_gmt":"2021-05-05T04:11:58","guid":{"rendered":"https:\/\/www.rushworth.us\/lisa\/?p=7760"},"modified":"2021-05-06T10:00:37","modified_gmt":"2021-05-06T15:00:37","slug":"oracle-collections-and-in-or-like-queries","status":"publish","type":"post","link":"https:\/\/www.rushworth.us\/lisa\/?p=7760","title":{"rendered":"Oracle &#8211; Collections and IN or LIKE Queries"},"content":{"rendered":"\n<p>I&#8217;ve been retrofitting a <em>lot<\/em> of PHP\/SQL queries to use oci_bind_by_name recently. When using &#8220;IN&#8221; clauses, you <em>can<\/em> iterate through your array twice, but it&#8217;s an inefficient approach.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n\/\/ Build the query string with a bunch of placeholders\n$strQuery = &quot;select Col1, Col2, Col3 from TableName where ColName IN (&quot;;\nfor($i=0; $i &lt; count($array); $i++){\n    if($i &gt; 0){\n        $strQuery = $strQuery . &quot;, &quot;;\n    }\n    $strQuery = $strQuery . &quot;:bindvar&quot; . $i;\n}\n$strQuery = $strQuery . &quot;)&quot;;\n... \n\/\/ Then bind each placeholder to something\nfor($i=0; $i &lt; count($array); $i++){\n    oci_bind_by_name($stmt, &quot;:bindvar&quot;.$i, $array&#x5B;$i]);\n}\n\n<\/pre><\/div>\n\n\n<p>Building a table from the array data and using an Oracle collection object creates cleaner code and avoids a second iteration of the array:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n$strQuery = &quot;SELECT indexID, objName FROM table WHERE objName in (SELECT column_value FROM table(:myIds))&quot;;\n$stmt = oci_parse($conn, $strQuery);\n\n$coll = oci_new_collection($kpiprd_conn, &#039;ODCIVARCHAR2LIST&#039;,&#039;SYS&#039;);\nforeach ($arrayValues as $strValue) {\n     $coll-&gt;append($strValue);\n}\noci_bind_by_name($stmt, &#039;:myIds&#039;, $coll, -1, OCI_B_NTY);\noci_set_prefetch($stmt, 300);\noci_execute($stmt);\n<\/pre><\/div>\n\n\n<p>A simple like clause is quite straight-forward<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n$strNameLikeString = &quot;SomeName%&quot;;\n$strQuery = &quot;SELECT ds_dvrsty_set_nm from ds_dvrsty_set WHERE ds_dvrsty_set_nm LIKE :divsetnm ORDER BY ds_dvrsty_set_nm DESC fetch first 1 row only&quot;;\n\n$stmt = oci_parse($connDB, $strQuery);\noci_bind_by_name($stmt, &quot;:divsetnm&quot;, $strNameLikeString);\noci_set_prefetch($stmt, 300);\noci_execute($stmt);\n\n<\/pre><\/div>\n\n\n<p>But what about an array of inputs essentially reproducing the LIKE ANY predicate in PostgreSQL? There&#8217;s not a direct equivalent in Oracle, and iterating through the array twice to build out a query WHERE (Field1 LIKE &#8216;Thing1%&#8217; OR Field1 LIKE &#8216;Thing2%&#8217; OR Field1 LIKE &#8216;Thing3%&#8217;) is undesirable. The with EXISTS allows me to create a LIKE ANY type query and only iterate through my array once to bind variables to placeholders using the same collection approach as was used with the IN clause. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n$arrayLocs = array(&#039;ERIEPAXE%&#039;, &#039;HNCKOHXA%&#039;, &#039;LTRKARXK%&#039;);\n$strQuery = &quot;SELECT location_id, clli_code FROM network_location WHERE EXISTS (select 1 FROM TABLE(:likelocs) WHERE clli_code LIKE column_value)&quot;;\n$stmt = oci_parse($connDB, $strQuery);\n\n$coll = oci_new_collection($connDB, &#039;ODCIVARCHAR2LIST&#039;,&#039;SYS&#039;);\nforeach ($arrayLocs as $strLocation) {\n    $coll-&gt;append($strLocation);\n}\noci_bind_by_name($stmt, &#039;:likelocs&#039;, $coll, -1, OCI_B_NTY);\noci_execute($stmt);\nprint &quot;&lt;table&gt;\\n&quot;;\nprint &quot;&lt;tr&gt;&lt;th&gt;Loc ID&lt;\/th&gt;&lt;th&gt;CLLI&lt;\/th&gt;&lt;\/tr&gt;\\n&quot;;\nwhile ($row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_NULLS)) {\n    print &quot;&lt;tr&gt;&lt;td&gt;&quot; . $row&#x5B;&#039;LOCATION_ID&#039;] . &quot;&lt;\/td&gt;&lt;td&gt;&quot; . $row&#x5B;&#039;CLLI_CODE&#039;] . &quot;&lt;\/td&gt;&lt;\/tr&gt;\\n&quot;;\n}\nprint &quot;&lt;\/table&gt;\\n&quot;;\n<\/pre><\/div>\n\n\n<p>There are many different collection types in Oracle which can be used with oci_new_collection. A full list of the system collection types can be queried from the database. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nSELECT * FROM SYS.ALL_TYPES WHERE TYPECODE = &#039;COLLECTION&#039; and OWNER = &#039;SYS&#039;;\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been retrofitting a lot of PHP\/SQL queries to use oci_bind_by_name recently. When using &#8220;IN&#8221; clauses, you can iterate through your array twice, but it&#8217;s an inefficient approach. Building a table from the array data and using an Oracle collection object creates cleaner code and avoids a second iteration of the array: A simple like &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,1004],"tags":[595,35],"class_list":["post-7760","post","type-post","status-publish","format-standard","hentry","category-coding","category-oracle","tag-oracle","tag-php"],"_links":{"self":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/7760","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7760"}],"version-history":[{"count":3,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/7760\/revisions"}],"predecessor-version":[{"id":7789,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/7760\/revisions\/7789"}],"wp:attachment":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7760"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7760"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7760"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}