{"id":8276,"date":"2018-05-06T12:22:59","date_gmt":"2018-05-06T10:22:59","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=8276"},"modified":"2023-11-08T01:36:39","modified_gmt":"2023-11-08T00:36:39","slug":"why-and-how-using-the-accessible_by_clause","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/","title":{"rendered":"Why and How Using the accessible_by_clause"},"content":{"rendered":"\n<p>The <code>accessible_by_clause<\/code> was introduced in Oracle Database 12 Release 1 and extended in Release 2. If you don\u2018t know this feature, I suggest having a look at the documentation or reading <a href=\"http:\/\/stevenfeuersteinonplsql.blogspot.ch\/2017\/02\/enhanced-whitelist-management-in-122.html\">Steven Feuerstein&#8217;s blog post<\/a>.<\/p>\n\n\n\n<p>In this blog post, I talk about how to use this feature properly.<\/p>\n\n\n\n<p>Consider you have a schema <code>the_api<\/code> and there&#8217;s a package <code>math<\/code> with the following signature:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">1) package math<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE the_api.math AS\n   \/**\n   * Calculates the sum of all integers found in a string.\n   *\n   * @param in_integers string containing integers to be summarized\n   * @returns sum, NULL if no integers are found\n   *\/\n   FUNCTION get_sum(\n      in_integers IN VARCHAR2\n   ) RETURN INTEGER DETERMINISTIC;\n\n   \/**\n   * Calculates the digit sum of an integer.\n   *\n   * @param in_integer input integer to calculate cross sum from \n   * @returns cross sum, NULL if input is NULL\n   *\/\n   FUNCTION get_cross_sum(\n      in_integer IN INTEGER\n   ) RETURN INTEGER DETERMINISTIC;\nEND math;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Calculates the sum of all integers found in a string.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integers string containing integers to be summarized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns sum, NULL if no integers are found<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Calculates the digit sum of an integer.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integer input integer to calculate cross sum from <\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns cross sum, NULL if input is NULL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integer <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> math;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The next query uses the provided functions <code>get_sum<\/code> and <code>get_cross_sum<\/code>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">2) using functions in package math<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SELECT the_api.math.get_sum('What is the sum of 5, 7, 13 and 17?') AS the_sum,\n       the_api.math.get_cross_sum(3456789) AS the_cross_sum\n  FROM dual;\n\n   THE_SUM THE_CROSS_SUM\n---------- -------------\n        42            42\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> the_api.math.get_sum(<\/span><span style=\"color: #CE9178\">&#39;What is the sum of 5, 7, 13 and 17?&#39;<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> the_sum,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       the_api.math.get_cross_sum(<\/span><span style=\"color: #B5CEA8\">3456789<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> the_cross_sum<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> dual;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   THE_SUM THE_CROSS_SUM<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">---------- -------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #B5CEA8\">42<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">No <code>accessible_by_clause<\/code><\/h2>\n\n\n\n<p>In an Oracle Database 11g the package body might be implemented like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">3) package body math<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE BODY the_api.math AS\n   FUNCTION get_sum(\n      in_integers IN sys.ora_mining_number_nt\n   ) RETURN INTEGER DETERMINISTIC IS\n      l_result INTEGER;\n   BEGIN\n      SELECT sum(column_value)\n        INTO l_result\n        FROM table(in_integers);\n      RETURN l_result;\n   END get_sum;\n\n   FUNCTION to_int_table(\n      in_integers IN VARCHAR2,\n      in_pattern  IN VARCHAR2 DEFAULT '[0-9]+'\n   ) RETURN sys.ora_mining_number_nt DETERMINISTIC IS\n      l_result sys.ora_mining_number_nt := sys.ora_mining_number_nt();\n      l_pos    INTEGER := 1;\n      l_int    INTEGER;\n   BEGIN\n      <<integer_tokens&gt;&gt;\n      LOOP\n         l_int := to_number(regexp_substr(in_integers, in_pattern, 1, l_pos));\n         EXIT integer_tokens WHEN l_int IS NULL;\n         l_result.EXTEND;\n         l_result(l_pos) := l_int;\n         l_pos := l_pos + 1;\n      END LOOP integer_tokens;\n      RETURN l_result;\n   END to_int_table;\n\n   FUNCTION get_sum(\n      in_integers IN VARCHAR2\n   ) RETURN INTEGER DETERMINISTIC IS\n   BEGIN\n      RETURN get_sum(to_int_table(in_integers));\n   END get_sum;\n\n   FUNCTION get_cross_sum(\n      in_integer IN INTEGER\n   ) RETURN INTEGER DETERMINISTIC IS\n   BEGIN\n      RETURN get_sum(to_int_table(to_char(in_integer), '[0-9]'));       \n   END get_cross_sum;\nEND math;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE BODY<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">sum<\/span><span style=\"color: #D4D4D4\">(column_value)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">INTO<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_result<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\">(in_integers);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_sum;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">to_int_table<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      in_pattern  <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;[0-9]+&#39;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt := sys.ora_mining_number_nt();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_int<\/span><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &lt;&lt;integer_tokens&gt;&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">LOOP<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #9CDCFE\">l_int<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #DCDCAA\">to_number<\/span><span style=\"color: #D4D4D4\">(regexp_substr(in_integers, in_pattern, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #569CD6\">EXIT<\/span><span style=\"color: #D4D4D4\"> integer_tokens <\/span><span style=\"color: #569CD6\">WHEN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_int<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS NULL<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #DCDCAA\">.EXTEND<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\">) := <\/span><span style=\"color: #9CDCFE\">l_int<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">END LOOP<\/span><span style=\"color: #D4D4D4\"> integer_tokens;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> to_int_table;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> get_sum(to_int_table(in_integers));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_sum;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integer <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> get_sum(to_int_table(<\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(in_integer), <\/span><span style=\"color: #CE9178\">&#39;[0-9]&#39;<\/span><span style=\"color: #D4D4D4\">));       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_cross_sum;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> math;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The private functions <code>get_sum<\/code> and <code>to_int_table<\/code> are doing the real work. Here are some issues with this code<\/p>\n\n\n\n<p><strong>1. Use of undocumented collection type&nbsp;<code>sys.ora_mining_number_nt<\/code><\/strong><\/p>\n\n\n\n<p>The private functions avoid the use of their own type, something like CREATE TYPE t_integer_type IS TABLE OF INTEGER. This shortcut is hidden and not part of the API. It is not super elegant, but quite common and easy to fix when Oracle decides to remove this collection type in a future release or to protect it with an <code>accessible_by_clause<\/code>. So I do not consider this a real problem and will not deal with it in this blog post.<\/p>\n\n\n\n<p><strong>2. Private function definitions must be ordered according its usage<\/strong><\/p>\n\n\n\n<p>The private functions are listed at the top of the package body, hence no forward declarations are necessary. Forward declarations lead to some confusion since IDEs do not distinguish between declarations and definitions in the outline window and you often end up selecting the wrong one. However, without forward declaration you have to order your private functions according its usage, which might break your domain-specific ordering logic.<\/p>\n\n\n\n<p><strong>3. Private functions are not documented<\/strong><\/p>\n\n\n\n<p>I usually document the signature of a PL\/SQL unit in the package specification only, that&#8217;s supported by\u00a0<a href=\"http:\/\/pldoc.sourceforge.net\/maven-site\/\">PLDoc<\/a>. Hence the private functions are treated like second-class citizens and left undocumented.<\/p>\n\n\n\n<p><strong>4. Private functions cannot be unit-tested<\/strong><\/p>\n\n\n\n<p>I&#8217;m not really a testing advocate. But as a developer, I&#8217;d like to know if my code works. I have to run it somehow. Usually more than once to get a working result. Hence I create scripts or unit tests. It is not possible to unit test the private functions directly. They have to be tested through public functions <code>get_sum<\/code> and <code>get_cross_sum<\/code>. In this case I&#8217;d like to test the private function <code>to_int_table<\/code> directly.<\/p>\n\n\n\n<p>The <code>accessible_by_clause<\/code>&nbsp;can address issues 2, 3 and 4 without implicitly extending the API.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Package-Level <code>accessible_by_clause<\/code><\/h2>\n\n\n\n<p>In Oracle Database 12c Release 1, the accessible_by_clause was introduced on the package level. This allows us to move the private functions\u00a0from the package <code>math<\/code> into a dedicated package <code>math_internal<\/code> with restricted access.\u00a0 Here&#8217;s the refactoring result:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">4) using accessible_by_clause on package level<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE the_api.math_internal  \n   ACCESSIBLE BY (PACKAGE the_api.math, PACKAGE the_api.test_math_internal) \nAS\n   \/**\n   * Calculates the sum of all integers in a collection.\n   *\n   * @param in_integers collection of integers to be summarized\n   * @returns sum, NULL if collection is empty\n   *\/\n   FUNCTION get_sum(\n     in_integers IN sys.ora_mining_number_nt\n   ) RETURN INTEGER DETERMINISTIC;\n\n   \/**\n   * Finds integer tokens in string.\n   *\n   * @param in_integers string containing integers to be tokenized\n   * @param in_pattern regular expression for integers\n   * @returns table of integers\n   *\/\n    FUNCTION to_int_table(\n      in_integers IN VARCHAR2,\n      in_pattern  IN VARCHAR2 DEFAULT '[0-9]+'\n   ) RETURN sys.ora_mining_number_nt DETERMINISTIC;\nEND math_internal;\n\/\n\nCREATE OR REPLACE PACKAGE the_api.math AS\n   \/**\n   * Calculates the sum of all integers found in a string.\n   *\n   * @param in_integers string containing integers to be summarized\n   * @returns sum, NULL if no integers are found\n   *\/\n   FUNCTION get_sum(\n      in_integers IN VARCHAR2\n   ) RETURN INTEGER DETERMINISTIC;\n\n   \/**\n   * Calculates the digit sum of an integer.\n   *\n   * @param in_integer input integer to calculate cross sum from \n   * @returns cross sum, NULL if input is NULL\n   *\/\n   FUNCTION get_cross_sum(\n      in_integer IN INTEGER\n   ) RETURN INTEGER DETERMINISTIC;\nEND math;\n\/\n\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math_internal<\/span><span style=\"color: #D4D4D4\">  <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   ACCESSIBLE BY (<\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math,<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.test_math_internal)<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">AS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Calculates the sum of all integers in a collection.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integers collection of integers to be summarized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns sum, NULL if collection is empty<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Finds integer tokens in string.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integers string containing integers to be tokenized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_pattern regular expression for integers<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns table of integers<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">to_int_table<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_pattern  <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;[0-9]+&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> math_internal;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Calculates the sum of all integers found in a string.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integers string containing integers to be summarized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns sum, NULL if no integers are found<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Calculates the digit sum of an integer.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integer input integer to calculate cross sum from <\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns cross sum, NULL if input is NULL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integer <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> math;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The <code>accessible_by_clause<\/code> defined on line 2 restricts access to the package <code>math<\/code>\u00a0and the package <code>test_math_internal<\/code>.\u00a0 It is important to note that the units referenced in the <code>accessible_by_clause<\/code> are not checked for existence when compiling PL\/SQL definitions, hence it is perfectly fine to list PL\/SQL units in the <code>accessible_by_clause<\/code>\u00a0which might not exist in a production environment, such as the utPLSQL unit test package <code>test_math_internal<\/code>.<\/p>\n\n\n\n<p>With this change, I address the previously mentioned issues 2, 3 and 4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>There are no private functions anymore, hence the order in the code is irrelevant<\/li>\n\n\n\n<li>All functions are documented<\/li>\n\n\n\n<li>All functions can be unit-tested<\/li>\n<\/ul>\n\n\n\n<p>Looks good, right? Yes and no. This change created some new issues.<\/p>\n\n\n\n<p><strong>5. Splitting code that belongs together<\/strong><\/p>\n\n\n\n<p>The original <code>math<\/code> the package was reasonably small and contained the whole processing logic. Now the package is divided into two packages and the code is spread into 4 files in the VCS (2 package specification files and 2 package body files).\u00a0 This accessiblity_clause is driving my PL\/SQL code structure. This might be good in some cases, but in this case, I do not like it.<\/p>\n\n\n\n<p><strong>6. Accessibility per package leads to more code splitting<\/strong><\/p>\n\n\n\n<p>Remember I just wanted to unit-test the function to_int_table. Now I can also unit-test the function <code>get_sum<\/code> since it is defined in the same package. It would look incomplete, if my unit tests would not cover <code>get_sum<\/code>, right? So, if I want to express that <code>get_sum<\/code> does not need an explicit unit test, I have to split the package <code>math_internal<\/code> further. For example into <code>math_internal1<\/code> and <code>math_internal2<\/code> and only the one containing the function <code>to_int_table<\/code> will have an accessor for the test package. This clearly shows that the granularity of the <code>accessible_by_clause<\/code> is too coarse-grained.<\/p>\n\n\n\n<p>\u00a0We can address these issues with an <code>accessible_by_clause<\/code> on the unit level.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Unit-Level <code>accessible_by_clause<\/code><\/h2>\n\n\n\n<p>Since Oracle Database 12c Release 2 the <code>accessible_by_clause<\/code> can be defined per package suprogram. This allows us to keep all subprograms in one package while addressing all previously described issues.&nbsp;Here&#8217;s the refactoring result:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">5) using accessible_by_clause on unit level (specification)<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE the_api.math AS\n   \/**\n   * Calculates the sum of all integers found in a string.\n   *\n   * @param in_integers string containing integers to be summarized\n   * @returns sum, NULL if no integers are found\n   *\/\n   FUNCTION get_sum(\n      in_integers IN VARCHAR2\n   ) RETURN INTEGER DETERMINISTIC;\n\n   \/**\n   * Calculates the digit sum of an integer.\n   *\n   * @param in_integer input integer to calculate cross sum from \n   * @returns cross sum, NULL if input is NULL\n   *\/\n   FUNCTION get_cross_sum(\n      in_integer IN INTEGER\n   ) RETURN INTEGER DETERMINISTIC;\n\n   \/**\n   * Calculates the sum of all integers in a collection.\n   *\n   * @param in_integers collection of integers to be summarized\n   * @returns sum, NULL if collection is empty\n   *\/\n   FUNCTION get_sum(\n     in_integers IN sys.ora_mining_number_nt\n   ) RETURN INTEGER DETERMINISTIC \n   ACCESSIBLE BY (PACKAGE the_api.math);\n\n   \/**\n   * Finds integer tokens in string.\n   *\n   * @param in_integers string containing integers to be tokenized\n   * @param in_pattern regular expression for integers\n   * @returns table of integers\n   *\/\n    FUNCTION to_int_table(\n      in_integers IN VARCHAR2,\n      in_pattern  IN VARCHAR2 DEFAULT '[0-9]+'\n   ) RETURN sys.ora_mining_number_nt DETERMINISTIC\n   ACCESSIBLE BY (PACKAGE the_api.math, PACKAGE the_api.test_math);\nEND math;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Calculates the sum of all integers found in a string.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integers string containing integers to be summarized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns sum, NULL if no integers are found<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Calculates the digit sum of an integer.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integer input integer to calculate cross sum from <\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns cross sum, NULL if input is NULL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integer <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Calculates the sum of all integers in a collection.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integers collection of integers to be summarized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns sum, NULL if collection is empty<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   ACCESSIBLE BY (<\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">\/**<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * Finds integer tokens in string.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_integers string containing integers to be tokenized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @param in_pattern regular expression for integers<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   * @returns table of integers<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   *\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">to_int_table<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_pattern  <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;[0-9]+&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   ACCESSIBLE BY (<\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math,<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.test_math);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> math;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>On line 31 the access to the overloaded function <code>get_sum<\/code> is restricted to this package. It&#8217;s semantically clear that this function cannot be unit-tested. On line 44 access to the function to_int_table is restricted to this package and the package test_math. Hence it is possible to unit-test this function in the package test_math.\u00a0 The package math is not split up and the access to the original private functions is properly protected.<\/p>\n\n\n\n<p>The package body looks quite similar to the original one. I&#8217;ve just put the access-restricted units at the bottom, to match the order and the signature in the specification.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">6) using accessible_by_clause on unit level (body)<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE BODY the_api.math AS\n   FUNCTION get_sum(in_integers IN VARCHAR2) RETURN INTEGER DETERMINISTIC IS\n   BEGIN\n      RETURN math.get_sum(math.to_int_table(in_integers));\n   END get_sum;\n\n   FUNCTION get_cross_sum(in_integer IN INTEGER) RETURN INTEGER DETERMINISTIC IS\n   BEGIN\n      RETURN math.get_sum(math.to_int_table(to_char(in_integer), '[0-9]'));       \n   END get_cross_sum;\n\n   FUNCTION get_sum(\n      in_integers IN sys.ora_mining_number_nt\n   ) RETURN INTEGER DETERMINISTIC\n      ACCESSIBLE BY (PACKAGE the_api.math)\n   IS\n      l_result INTEGER;\n   BEGIN\n      SELECT sum(column_value)\n        INTO l_result\n        FROM table(in_integers);\n      RETURN l_result;\n   END get_sum;\n\n   FUNCTION to_int_table(\n      in_integers IN VARCHAR2,\n      in_pattern  IN VARCHAR2 DEFAULT '[0-9]+'\n   ) RETURN sys.ora_mining_number_nt DETERMINISTIC \n      ACCESSIBLE BY (PACKAGE the_api.math, PACKAGE the_api.test_math)\n   IS\n      l_result sys.ora_mining_number_nt := sys.ora_mining_number_nt();\n      l_pos    INTEGER := 1;\n      l_int    INTEGER;\n   BEGIN\n      <<integer_tokens&gt;&gt;\n      LOOP\n         l_int := to_number(regexp_substr(in_integers, in_pattern, 1, l_pos));\n         EXIT integer_tokens WHEN l_int IS NULL;\n         l_result.EXTEND;\n         l_result(l_pos) := l_int;\n         l_pos := l_pos + 1;\n      END LOOP integer_tokens;\n      RETURN l_result;\n   END to_int_table;\nEND math;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE BODY<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> math.get_sum(math.to_int_table(in_integers));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_sum;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum<\/span><span style=\"color: #D4D4D4\">(in_integer <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> math.get_sum(math.to_int_table(<\/span><span style=\"color: #DCDCAA\">to_char<\/span><span style=\"color: #D4D4D4\">(in_integer), <\/span><span style=\"color: #CE9178\">&#39;[0-9]&#39;<\/span><span style=\"color: #D4D4D4\">));       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_cross_sum;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      ACCESSIBLE BY (<\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">sum<\/span><span style=\"color: #D4D4D4\">(column_value)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">INTO<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_result<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">table<\/span><span style=\"color: #D4D4D4\">(in_integers);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_sum;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">to_int_table<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_integers <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      in_pattern  <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;[0-9]+&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">      ACCESSIBLE BY (<\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math,<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.test_math)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt := sys.ora_mining_number_nt();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_int<\/span><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &lt;&lt;integer_tokens&gt;&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">LOOP<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #9CDCFE\">l_int<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #DCDCAA\">to_number<\/span><span style=\"color: #D4D4D4\">(regexp_substr(in_integers, in_pattern, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #569CD6\">EXIT<\/span><span style=\"color: #D4D4D4\"> integer_tokens <\/span><span style=\"color: #569CD6\">WHEN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_int<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS NULL<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #DCDCAA\">.EXTEND<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\">) := <\/span><span style=\"color: #9CDCFE\">l_int<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #9CDCFE\">l_pos<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">END LOOP<\/span><span style=\"color: #D4D4D4\"> integer_tokens;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> to_int_table;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> math;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Taking about unit testing without showing a unit test is a bit inauthentic. So, here is the utPLSQL test package:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">7) utPLSQL unit tests<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE the_api.test_math IS\n   --%suite\n\n   --%test\n   PROCEDURE get_sum_1;\n\n   --%test\n   PROCEDURE get_sum_2;\n \n   --%test\n   PROCEDURE get_cross_sum_1;\n\n   --%test\n   PROCEDURE get_cross_sum_2;\n\n   --%test\n   PROCEDURE to_int_table_1;\n\n   --%test\n   PROCEDURE to_int_table_2;\nEND test_math;\n\/\n\nCREATE OR REPLACE PACKAGE BODY the_api.test_math IS\n   PROCEDURE get_sum_1 IS\n   BEGIN\n      ut.expect(42).to_equal(the_api.math.get_sum('What is the sum of 5, 7, 13 and 17?'));\n   END get_sum_1;\n   \n   PROCEDURE get_sum_2 IS\n   BEGIN\n      ut.expect(CAST(NULL AS INTEGER)).to_equal(the_api.math.get_sum('What is the sum?'));\n   END get_sum_2; \n\n   PROCEDURE get_cross_sum_1 IS\n   BEGIN\n      ut.expect(42).to_equal(the_api.math.get_cross_sum(3456789));\n   END get_cross_sum_1;\n   \n   PROCEDURE get_cross_sum_2 IS\n   BEGIN\n      ut.expect(CAST(NULL AS INTEGER)).to_equal(the_api.math.get_cross_sum(NULL));\n   END get_cross_sum_2;\n\n   PROCEDURE to_int_table_1 IS\n      l_expected sys.ora_mining_number_nt;\n      l_actual   sys.ora_mining_number_nt;\n   BEGIN\n      l_expected := sys.ora_mining_number_nt(5, 7, 13, 17);\n      l_actual := math.to_int_table('What is the sum of 5, 7, 13 and 17?');\n      ut.expect(anydata.convertCollection(l_expected)).to_equal(anydata.convertCollection(l_actual));\n   END to_int_table_1;\n\n   PROCEDURE to_int_table_2 IS\n      l_expected sys.ora_mining_number_nt;\n      l_actual   sys.ora_mining_number_nt;\n   BEGIN\n      l_expected := sys.ora_mining_number_nt();\n      l_actual := math.to_int_table(NULL);\n      ut.expect(anydata.convertCollection(l_expected)).to_equal(anydata.convertCollection(l_actual));\n   END to_int_table_2;\nEND test_math;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.test_math<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%suite<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum_1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum_2<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum_1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum_2<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">to_int_table_1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #6A9955\">--%test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">to_int_table_2<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> test_math;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE BODY<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.test_math<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum_1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ut.expect(<\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">).to_equal(the_api.math.get_sum(<\/span><span style=\"color: #CE9178\">&#39;What is the sum of 5, 7, 13 and 17?&#39;<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_sum_1;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_sum_2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ut.expect(<\/span><span style=\"color: #DCDCAA\">CAST<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">)).to_equal(the_api.math.get_sum(<\/span><span style=\"color: #CE9178\">&#39;What is the sum?&#39;<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_sum_2; <\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum_1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ut.expect(<\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">).to_equal(the_api.math.get_cross_sum(<\/span><span style=\"color: #B5CEA8\">3456789<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_cross_sum_1;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">get_cross_sum_2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ut.expect(<\/span><span style=\"color: #DCDCAA\">CAST<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">)).to_equal(the_api.math.get_cross_sum(<\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> get_cross_sum_2;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">to_int_table_1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_expected<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_actual<\/span><span style=\"color: #D4D4D4\">   sys.ora_mining_number_nt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_expected<\/span><span style=\"color: #D4D4D4\"> := sys.ora_mining_number_nt(<\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">7<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">13<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">17<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_actual<\/span><span style=\"color: #D4D4D4\"> := math.to_int_table(<\/span><span style=\"color: #CE9178\">&#39;What is the sum of 5, 7, 13 and 17?&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ut.expect(anydata.convertCollection(<\/span><span style=\"color: #9CDCFE\">l_expected<\/span><span style=\"color: #D4D4D4\">)).to_equal(anydata.convertCollection(<\/span><span style=\"color: #9CDCFE\">l_actual<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> to_int_table_1;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">PROCEDURE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">to_int_table_2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_expected<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_actual<\/span><span style=\"color: #D4D4D4\">   sys.ora_mining_number_nt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_expected<\/span><span style=\"color: #D4D4D4\"> := sys.ora_mining_number_nt();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">l_actual<\/span><span style=\"color: #D4D4D4\"> := math.to_int_table(<\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ut.expect(anydata.convertCollection(<\/span><span style=\"color: #9CDCFE\">l_expected<\/span><span style=\"color: #D4D4D4\">)).to_equal(anydata.convertCollection(<\/span><span style=\"color: #9CDCFE\">l_actual<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> to_int_table_2;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> test_math;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Running utPLSQL tests is easy, see:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">8) running utPLSQL tests<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SET SERVEROUTPUT ON SIZE UNLIMITED\nEXECUTE ut.run('THE_API.TEST_MATH');\n\ntest_math\n  get_sum_1 [.004 sec]\n  get_sum_2 [.004 sec]\n  get_cross_sum_1 [.004 sec]\n  get_cross_sum_2 [.004 sec]\n  to_int_table_1 [.009 sec]\n  to_int_table_2 [.007 sec]\n \nFinished in .034975 seconds\n6 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)\n \n\n\nPL\/SQL procedure successfully completed.\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SET<\/span><span style=\"color: #D4D4D4\"> SERVEROUTPUT <\/span><span style=\"color: #569CD6\">ON<\/span><span style=\"color: #D4D4D4\"> SIZE UNLIMITED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">EXECUTE ut.run(<\/span><span style=\"color: #CE9178\">&#39;THE_API.TEST_MATH&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">test_math<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  get_sum_1 [.<\/span><span style=\"color: #B5CEA8\">004<\/span><span style=\"color: #D4D4D4\"> sec]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  get_sum_2 [.<\/span><span style=\"color: #B5CEA8\">004<\/span><span style=\"color: #D4D4D4\"> sec]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  get_cross_sum_1 [.<\/span><span style=\"color: #B5CEA8\">004<\/span><span style=\"color: #D4D4D4\"> sec]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  get_cross_sum_2 [.<\/span><span style=\"color: #B5CEA8\">004<\/span><span style=\"color: #D4D4D4\"> sec]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  to_int_table_1 [.<\/span><span style=\"color: #B5CEA8\">009<\/span><span style=\"color: #D4D4D4\"> sec]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  to_int_table_2 [.<\/span><span style=\"color: #B5CEA8\">007<\/span><span style=\"color: #D4D4D4\"> sec]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Finished <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> .<\/span><span style=\"color: #B5CEA8\">034975<\/span><span style=\"color: #D4D4D4\"> seconds<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\"> tests, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\"> failed, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\"> errored, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\"> disabled, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\"> warning(s)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">PL\/<\/span><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\"> procedure successfully completed.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Start using the <code>accessible_by_clause<\/code>. But using the <code>accessible_by_clause<\/code> should not drive the way you structure your PL\/SQL code. It certainly should not lead to a code-splitting avalanche. Hence I favour the definition of the <code>accessible_by_clause<\/code> on the subprogram level.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The accessible_by_clause was introduced in Oracle Database 12 Release 1 and extended in Release 2. If you don\u2018t know this feature, I suggest having a look at the documentation or reading Steven Feuerstein&#8217;s blog post. In this blog post, I talk about how to use this feature properly. Consider you have a<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":9523,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[106,13,85,105],"class_list":["post-8276","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-accessible_by_clause","tag-plsql","tag-sql","tag-utplsql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Why and How Using the accessible_by_clause - Philipp Salvisberg&#039;s 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.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Why and How Using the accessible_by_clause - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"The accessible_by_clause was introduced in Oracle Database 12 Release 1 and extended in Release 2. If you don\u2018t know this feature, I suggest having a look at the documentation or reading Steven Feuerstein&#8217;s blog post. In this blog post, I talk about how to use this feature properly. Consider you have a [\u2026]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-05-06T10:22:59+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-08T00:36:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2018\/05\/accessible_by_clause.png\" \/>\n\t<meta property=\"og:image:width\" content=\"574\" \/>\n\t<meta property=\"og:image:height\" content=\"453\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Philipp Salvisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:site\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Salvisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"Why and How Using the accessible_by_clause\",\"datePublished\":\"2018-05-06T10:22:59+00:00\",\"dateModified\":\"2023-11-08T00:36:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/\"},\"wordCount\":957,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/05\\\/accessible_by_clause.png\",\"keywords\":[\"accessible_by_clause\",\"PL\\\/SQL\",\"SQL\",\"utPLSQL\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/\",\"name\":\"Why and How Using the accessible_by_clause - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/05\\\/accessible_by_clause.png\",\"datePublished\":\"2018-05-06T10:22:59+00:00\",\"dateModified\":\"2023-11-08T00:36:39+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/05\\\/accessible_by_clause.png\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/05\\\/accessible_by_clause.png\",\"width\":574,\"height\":453},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2018\\\/05\\\/06\\\/why-and-how-using-the-accessible_by_clause\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Why and How Using the accessible_by_clause\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\",\"name\":\"Philipp Salvisberg&#039;s Blog\",\"description\":\"Database-centric development\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\",\"name\":\"Philipp Salvisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"width\":400,\"height\":400,\"caption\":\"Philipp Salvisberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\"},\"sameAs\":[\"http:\\\/\\\/www.salvis.com\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Why and How Using the accessible_by_clause - Philipp Salvisberg&#039;s 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.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/","og_locale":"en_US","og_type":"article","og_title":"Why and How Using the accessible_by_clause - Philipp Salvisberg&#039;s Blog","og_description":"The accessible_by_clause was introduced in Oracle Database 12 Release 1 and extended in Release 2. If you don\u2018t know this feature, I suggest having a look at the documentation or reading Steven Feuerstein&#8217;s blog post. In this blog post, I talk about how to use this feature properly. Consider you have a [\u2026]","og_url":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2018-05-06T10:22:59+00:00","article_modified_time":"2023-11-08T00:36:39+00:00","og_image":[{"width":574,"height":453,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2018\/05\/accessible_by_clause.png","type":"image\/png"}],"author":"Philipp Salvisberg","twitter_card":"summary_large_image","twitter_creator":"@phsalvisberg","twitter_site":"@phsalvisberg","twitter_misc":{"Written by":"Philipp Salvisberg","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"Why and How Using the accessible_by_clause","datePublished":"2018-05-06T10:22:59+00:00","dateModified":"2023-11-08T00:36:39+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/"},"wordCount":957,"commentCount":3,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2018\/05\/accessible_by_clause.png","keywords":["accessible_by_clause","PL\/SQL","SQL","utPLSQL"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/","url":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/","name":"Why and How Using the accessible_by_clause - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2018\/05\/accessible_by_clause.png","datePublished":"2018-05-06T10:22:59+00:00","dateModified":"2023-11-08T00:36:39+00:00","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2018\/05\/accessible_by_clause.png","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2018\/05\/accessible_by_clause.png","width":574,"height":453},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2018\/05\/06\/why-and-how-using-the-accessible_by_clause\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Why and How Using the accessible_by_clause"}]},{"@type":"WebSite","@id":"https:\/\/www.salvis.com\/blog\/#website","url":"https:\/\/www.salvis.com\/blog\/","name":"Philipp Salvisberg&#039;s Blog","description":"Database-centric development","publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.salvis.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515","name":"Philipp Salvisberg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","width":400,"height":400,"caption":"Philipp Salvisberg"},"logo":{"@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg"},"sameAs":["http:\/\/www.salvis.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/8276","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/comments?post=8276"}],"version-history":[{"count":57,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/8276\/revisions"}],"predecessor-version":[{"id":12632,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/8276\/revisions\/12632"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/9523"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=8276"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=8276"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=8276"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}