{"id":4387,"date":"2015-03-03T18:47:19","date_gmt":"2015-03-03T17:47:19","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/"},"modified":"2015-03-03T18:47:19","modified_gmt":"2015-03-03T17:47:19","slug":"generic-query-for-multicriteria-search-part-i-useconcat-or-expansion","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/","title":{"rendered":"Generic query for multicriteria search &#8211; part I: USE_CONCAT (OR Expansion)"},"content":{"rendered":"<h2>By Franck Pachot<\/h2>\n<p>.<br \/>\nYou have a multicriteria search screen on the EMPLOYEE table where you can enter an employee id, a department id, a manager id or a job id. Either you put the value you want to filter on, or you leave it null when you don&#8217;t want to filter on it. How will you code that? You can build the query on the fly with dynamic SQL or use a generic query like this one:<\/p>\n<pre><code>       SELECT *\n       FROM employees\n       WHERE (job_id = NVL(:job_id, job_id))\n       AND (department_id = NVL(:department_id, department_id))\n       AND (manager_id = NVL(:manager_id, manager_id))\n       AND (employee_id = NVL(:employee_id, employee_id))\n<\/code><\/pre>\n<p>This is good for the code maintainability, but having a one-fit-all query will not be optimial for each cases. Markus Winand (every database developer should read his book) describes the danger ot that in his website: <a href=\"http:\/\/use-the-index-luke.com\/sql\/where-clause\/obfuscation\/smart-logic\">Use The Index, Luke<\/a><br \/>\nIn this post I&#8217;ll show the problem on the Oracle example schema HR and in the next post I&#8217;ll see how 11g Adaptive Cursor Sharing can help.<br \/>\nHere is the example to run on the HR schema. I declare the 4 variables in sqlplus:<\/p>\n<pre><code>SQL&gt;  variable job_id varchar2(20)\nSQL&gt;  variable department_id number\nSQL&gt;  variable manager_id number\nSQL&gt;  variable employee_id number\n<\/code><\/pre>\n<h3>All binds null<\/h3>\n<p>I assign null for all of them &#8211; meaning that I don&#8217;t want to filter anything:<\/p>\n<pre><code>SQL&gt; exec :job_id:=null; :department_id:=null; :manager_id:=null; :employee_id:=null;\nPL\/SQL procedure successfully completed.\n<\/code><\/pre>\n<p>and I run my generic query:<\/p>\n<pre><code>SQL&gt; \n     SELECT\n     COUNT(*)\n     FROM\n       (SELECT 1\n       FROM employees\n       WHERE (job_id = NVL(:job_id, job_id))\n       AND (department_id = NVL(:department_id, department_id))\n       AND (manager_id = NVL(:manager_id, manager_id))\n       AND (employee_id = NVL(:employee_id, employee_id))\n       )\nSQL&gt; \/\n\n  COUNT(*)\n----------\n       105\n<\/code><\/pre>\n<p>Let&#8217;s check the execution plan:<\/p>\n<pre><code>SQL&gt; select * from table(dbms_xplan.display_cursor(format=&gt;'allstats last +outline'));\n\nPLAN_TABLE_OUTPUT\n------------------------------------------------------------------------------------\nSQL_ID  5q737h3umyx3u, child number 0\n-------------------------------------\nSELECT  COUNT(*) FROM   (SELECT 1   FROM employees   WHERE (job_id =\nNVL(:job_id, job_id))   AND (department_id = NVL(:department_id,\ndepartment_id))   AND (manager_id = NVL(:manager_id, manager_id))   AND\n(employee_id = NVL(:employee_id, employee_id))   )\n\nPlan hash value: 3424141370\n\n------------------------------------------------------------------------------------\n| Id  | Operation                       | Name          | Starts | E-Rows | A-Rows |\n------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT                |               |      1 |        |      1 |\n|   1 |  SORT AGGREGATE                 |               |      1 |      1 |      1 |\n|   2 |   CONCATENATION                 |               |      1 |        |    105 |\n|*  3 |    FILTER                       |               |      1 |        |    105 |\n|*  4 |     TABLE ACCESS BY INDEX ROWID | EMPLOYEES     |      1 |    105 |    105 |\n|*  5 |      INDEX FULL SCAN            | EMP_EMP_ID_PK |      1 |    107 |    107 |\n|*  6 |    FILTER                       |               |      1 |        |      0 |\n|*  7 |     TABLE ACCESS BY INDEX ROWID | EMPLOYEES     |      0 |      1 |      0 |\n|*  8 |      INDEX UNIQUE SCAN          | EMP_EMP_ID_PK |      0 |      1 |      0 |\n------------------------------------------------------------------------------------\n<\/code><\/pre>\n<p>The CBO has used OR Expansion on the 4th predicate on employee_id. The execution has used the branch for all rows (the INDEX FULL SCAN) and the branch optimized to get only one employee (INDEX UNIQUE SCAN) has not been executed (Starts=0).<\/p>\n<p>Do you wonder why the optimizer has chosen a full scan on the index instead of the table? Because the predicate implicitely select only rows where EMPLOYEE_ID is not null, and I&#8217;ve probably not enough statistics and\/or constraint to let the optimizer know that all rows have an EMPLOYEE_ID. But that&#8217;s not the point here. I&#8217;m just using the HR schema as it is provided when creating the database with the example schemas.<\/p>\n<p>Here are the predicates where we see that the FILTER operations &#8211; line 3 and 6 &#8211; are on the predicate about :EMPLOYEE_ID being null or not:<\/p>\n<pre><code>Predicate Information (identified by operation id):\n---------------------------------------------------\n\n   3 - filter(:EMPLOYEE_ID IS NULL)\n   4 - filter((\"DEPARTMENT_ID\"=NVL(:DEPARTMENT_ID,\"DEPARTMENT_ID\") AND\n              \"MANAGER_ID\"=NVL(:MANAGER_ID,\"MANAGER_ID\") AND \"JOB_ID\"=NVL(:JOB_ID,\"JOB_ID\")))\n   5 - filter(\"EMPLOYEE_ID\" IS NOT NULL)\n   6 - filter(:EMPLOYEE_ID IS NOT NULL)\n   7 - filter((\"DEPARTMENT_ID\"=NVL(:DEPARTMENT_ID,\"DEPARTMENT_ID\") AND\n              \"MANAGER_ID\"=NVL(:MANAGER_ID,\"MANAGER_ID\") AND \"JOB_ID\"=NVL(:JOB_ID,\"JOB_ID\")))\n   8 - access(\"EMPLOYEE_ID\"=:EMPLOYEE_ID)\n<\/code><\/pre>\n<p>There is another way to see that the plan has done OR expansion on the 4th predicate:<\/p>\n<pre><code>Outline Data\n-------------\n\n  \/*+\n      BEGIN_OUTLINE_DATA\n      IGNORE_OPTIM_EMBEDDED_HINTS\n      OPTIMIZER_FEATURES_ENABLE('12.1.0.2')\n      DB_VERSION('12.1.0.2')\n      ALL_ROWS\n      OUTLINE_LEAF(@\"SEL$F5BB74E1\")\n      MERGE(@\"SEL$2\")\n      OUTLINE_LEAF(@\"SEL$F5BB74E1_1\")\n      USE_CONCAT(@\"SEL$F5BB74E1\" 8 OR_PREDICATES(4))\n      OUTLINE_LEAF(@\"SEL$F5BB74E1_2\")\n      OUTLINE(@\"SEL$1\")\n      OUTLINE(@\"SEL$2\")\n      OUTLINE(@\"SEL$F5BB74E1\")\n      MERGE(@\"SEL$2\")\n      INDEX(@\"SEL$F5BB74E1_1\" \"EMPLOYEES\"@\"SEL$2\" (\"EMPLOYEES\".\"EMPLOYEE_ID\"))\n      BATCH_TABLE_ACCESS_BY_ROWID(@\"SEL$F5BB74E1_1\" \"EMPLOYEES\"@\"SEL$2\")\n      INDEX_RS_ASC(@\"SEL$F5BB74E1_2\" \"EMPLOYEES\"@\"SEL$F5BB74E1_2\" (\"EMPLOYEES\".\"EMPLOYEE_ID\"))\n      END_OUTLINE_DATA\n  *\/\n<\/code><\/pre>\n<p>This is the OR Expansion optimizer transformation. It rewrites the statement as if we did a UNION ALL where each branch is optimized for one case. The plan shows CONCATENATION instead of the UNION ALL but it&#8217;s the same. The filter predicate makes only one branche active and you see it in the execution statistics &#8216;Starts&#8217; column.<\/p>\n<h3>query for one EMPLOYEE_ID<\/h3>\n<p>Now I bind a value to EMPLOYEE_ID:<\/p>\n<pre><code>SQL&gt; exec :job_id:=null; :department_id:=null; :manager_id:=null; :employee_id:=0;\nPL\/SQL procedure successfully completed.\n<\/code><\/pre>\n<p>and execute the same query as above:<\/p>\n<pre><code>SQL&gt; \/\n\n  COUNT(*)\n----------\n         0\n<\/code><\/pre>\n<p>We have the same plan as we reuse the same cursor (child number 0):<\/p>\n<pre><code>PLAN_TABLE_OUTPUT\n------------------------------------------------------------------------------------\nSQL_ID  5q737h3umyx3u, child number 0\n-------------------------------------\nSELECT  COUNT(*) FROM   (SELECT 1   FROM employees   WHERE (job_id =\nNVL(:job_id, job_id))   AND (department_id = NVL(:department_id,\ndepartment_id))   AND (manager_id = NVL(:manager_id, manager_id))   AND\n(employee_id = NVL(:employee_id, employee_id))   )\n\nPlan hash value: 3424141370\n\n------------------------------------------------------------------------------------\n| Id  | Operation                       | Name          | Starts | E-Rows | A-Rows |\n------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT                |               |      1 |        |      1 |\n|   1 |  SORT AGGREGATE                 |               |      1 |      1 |      1 |\n|   2 |   CONCATENATION                 |               |      1 |        |      0 |\n|*  3 |    FILTER                       |               |      1 |        |      0 |\n|*  4 |     TABLE ACCESS BY INDEX ROWID | EMPLOYEES     |      0 |    105 |      0 |\n|*  5 |      INDEX FULL SCAN            | EMP_EMP_ID_PK |      0 |    107 |      0 |\n|*  6 |    FILTER                       |               |      1 |        |      0 |\n|*  7 |     TABLE ACCESS BY INDEX ROWID | EMPLOYEES     |      1 |      1 |      0 |\n|*  8 |      INDEX UNIQUE SCAN          | EMP_EMP_ID_PK |      1 |      1 |      0 |\n------------------------------------------------------------------------------------\n<\/code><\/pre>\n<p>And now the branch optimized for one EMPLOYEE_ID is used (Starts=1), thanks to OR Expansion. This is good. The OR Expansion transformation makes it optimal when only one column is involved in the predicate.<\/p>\n<h3>Query for all employees but specific values on other columns<\/h3>\n<p>Here are my variable bindings:<\/p>\n<pre><code>SQL&gt; exec :job_id:='AC_MGR'; :department_id:=100; :manager_id:=0; :employee_id:=null;\nPL\/SQL procedure successfully completed.\n<\/code><\/pre>\n<p>I have predicates on all other columns (where I have indexes).<\/p>\n<pre><code>SQL&gt; \/\n\n  COUNT(*)\n----------\n         0\n<\/code><\/pre>\n<p>But the same cursor is still shared:<\/p>\n<pre><code>PLAN_TABLE_OUTPUT\n------------------------------------------------------------------------------------\nSQL_ID  5q737h3umyx3u, child number 0\n-------------------------------------\nSELECT  COUNT(*) FROM   (SELECT 1   FROM employees   WHERE (job_id =\nNVL(:job_id, job_id))   AND (department_id = NVL(:department_id,\ndepartment_id))   AND (manager_id = NVL(:manager_id, manager_id))   AND\n(employee_id = NVL(:employee_id, employee_id))   )\n\nPlan hash value: 3424141370\n\n------------------------------------------------------------------------------------\n| Id  | Operation                       | Name          | Starts | E-Rows | A-Rows |\n------------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT                |               |      1 |        |      1 |\n|   1 |  SORT AGGREGATE                 |               |      1 |      1 |      1 |\n|   2 |   CONCATENATION                 |               |      1 |        |      0 |\n|*  3 |    FILTER                       |               |      1 |        |      0 |\n|*  4 |     TABLE ACCESS BY INDEX ROWID | EMPLOYEES     |      1 |    105 |      0 |\n|*  5 |      INDEX FULL SCAN            | EMP_EMP_ID_PK |      1 |    107 |    107 |\n|*  6 |    FILTER                       |               |      1 |        |      0 |\n|*  7 |     TABLE ACCESS BY INDEX ROWID | EMPLOYEES     |      0 |      1 |      0 |\n|*  8 |      INDEX UNIQUE SCAN          | EMP_EMP_ID_PK |      0 |      1 |      0 |\n------------------------------------------------------------------------------------\n<\/code><\/pre>\n<p>and this is not optimal because there is no branch for those predicates. The FULL SCAN branch has been used and rows have been filtered only after the table access.<\/p>\n<h3>Bind Sensitive<\/h3>\n<p>The statement is marked as bind sensitive (I have histograms on those columns) the the cursor never becomes bind aware. Here it s after hundreds of executions with different combination of values and nulls:<\/p>\n<pre><code>SQL&gt; select child_number,executions,is_bind_sensitive,is_bind_aware from v$sql where sql_id='5q737h3umyx3u';\n\nCHILD_NUMBER EXECUTIONS IS_BIND_SENSITIVE IS_BIND_AWARE\n------------ ---------- ----------------- -------------\n           0        603 Y                 N       \n<\/code><\/pre>\n<h3>Bind Aware<\/h3>\n<p>So now, I want to try if I can solve the issue by adding the BIND_AWARE hint in the statement, in order to have different execution plans when providing different combination of values or nulls. But this is for the next blog post&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Franck Pachot . You have a multicriteria search screen on the EMPLOYEE table where you can enter an employee id, a department id, a manager id or a job id. Either you put the value you want to filter on, or you leave it null when you don&#8217;t want to filter on it. How [&hellip;]<\/p>\n","protected":false},"author":27,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[198,59],"tags":[],"type_dbi":[],"class_list":["post-4387","post","type-post","status-publish","format-standard","hentry","category-database-management","category-oracle"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Generic query for multicriteria search - part I: USE_CONCAT (OR Expansion) - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Generic query for multicriteria search - part I: USE_CONCAT (OR Expansion)\" \/>\n<meta property=\"og:description\" content=\"By Franck Pachot . You have a multicriteria search screen on the EMPLOYEE table where you can enter an employee id, a department id, a manager id or a job id. Either you put the value you want to filter on, or you leave it null when you don&#8217;t want to filter on it. How [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-03-03T17:47:19+00:00\" \/>\n<meta name=\"author\" content=\"Oracle Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Oracle Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/\"},\"author\":{\"name\":\"Oracle Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"headline\":\"Generic query for multicriteria search &#8211; part I: USE_CONCAT (OR Expansion)\",\"datePublished\":\"2015-03-03T17:47:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/\"},\"wordCount\":643,\"commentCount\":0,\"articleSection\":[\"Database management\",\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/\",\"name\":\"Generic query for multicriteria search - part I: USE_CONCAT (OR Expansion) - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2015-03-03T17:47:19+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Generic query for multicriteria search &#8211; part I: USE_CONCAT (OR Expansion)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\",\"name\":\"Oracle Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"caption\":\"Oracle Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Generic query for multicriteria search - part I: USE_CONCAT (OR Expansion) - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/","og_locale":"en_US","og_type":"article","og_title":"Generic query for multicriteria search - part I: USE_CONCAT (OR Expansion)","og_description":"By Franck Pachot . You have a multicriteria search screen on the EMPLOYEE table where you can enter an employee id, a department id, a manager id or a job id. Either you put the value you want to filter on, or you leave it null when you don&#8217;t want to filter on it. How [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/","og_site_name":"dbi Blog","article_published_time":"2015-03-03T17:47:19+00:00","author":"Oracle Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Oracle Team","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/"},"author":{"name":"Oracle Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"headline":"Generic query for multicriteria search &#8211; part I: USE_CONCAT (OR Expansion)","datePublished":"2015-03-03T17:47:19+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/"},"wordCount":643,"commentCount":0,"articleSection":["Database management","Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/","url":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/","name":"Generic query for multicriteria search - part I: USE_CONCAT (OR Expansion) - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2015-03-03T17:47:19+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/generic-query-for-multicriteria-search-part-i-useconcat-or-expansion\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Generic query for multicriteria search &#8211; part I: USE_CONCAT (OR Expansion)"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee","name":"Oracle Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","caption":"Oracle Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/4387","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=4387"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/4387\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=4387"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=4387"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=4387"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=4387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}