{"id":10395,"date":"2020-08-09T20:42:32","date_gmt":"2020-08-09T18:42:32","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=10395"},"modified":"2023-11-12T13:51:37","modified_gmt":"2023-11-12T12:51:37","slug":"formatting-sql-scripts-in-a-directory-tree-with-sqlcl","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/","title":{"rendered":"Formatting SQL Scripts in a Directory Tree with SQLcl"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>Oracle&#8217;s SQL Developer can format code in any worksheet and PL\/SQL editor. The formatter is highly configurable and the default formatting results are becoming better with every version. Oracle&#8217;s SQLcl is a command-line tool. It&#8217;s a stripped-down version of SQL Developer and is known as a user-friendly alternative for SQL*Plus.<\/p>\n\n\n\n<p>But SQLcl is more. It can execute JavaScript and access any Java class distributed with SQLcl. Through JavaScript, you can access local and remote resources easily. In this blog post, I show how you can format all your SQL scripts with a few lines of JavaScript.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Demo Setup<\/h2>\n\n\n\n<p>I re-formatted the following three SQL scripts by hand. The first two are ugly. In the end, I want to show that the formatter is an improvement, even if you do not agree with the applied style guideline. I think it is important to know how the formatter deals with syntax errors. That&#8217;s why I&#8217;ve added one to the last script.<\/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\">query.sql<\/span><span role=\"button\" tabindex=\"0\" data-code=\"Select d.department_name,v.  employee_id \n,v \n. last_name frOm departments d CROSS APPLY(select*from employees e\n  wHERE e.department_id=d.department_id) v WHeRE \nd.department_name in ('Marketing'\n,'Operations',\n'Public Relations') Order By d.\ndepartment_name,v.employee_id;\" 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\"> d.department_name,v.  employee_id <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">,v <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">. last_name <\/span><span style=\"color: #569CD6\">frOm<\/span><span style=\"color: #D4D4D4\"> departments d <\/span><span style=\"color: #569CD6\">CROSS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">APPLY<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\">*<\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> employees e<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">wHERE<\/span><span style=\"color: #D4D4D4\"> e.department_id=d.department_id) v <\/span><span style=\"color: #569CD6\">WHeRE<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">d.department_name <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #CE9178\">&#39;Marketing&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">,<\/span><span style=\"color: #CE9178\">&#39;Operations&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">&#39;Public Relations&#39;<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">Order By<\/span><span style=\"color: #D4D4D4\"> d.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">department_name,v.employee_id;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\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\">package_body.sql<\/span><span role=\"button\" tabindex=\"0\" data-code=\"create or replace package body the_api.math as function to_int_table(in_integers\nin varchar2,in_pattern in varchar2 default '[0-9]+')return sys.ora_mining_number_nt deterministic accessible\nby(package the_api.math,package the_api.test_math)is l_result sys\n.ora_mining_number_nt:=sys.ora_mining_number_nt();l_pos integer:= 1;l_int integer;\nbegin<<integer_tokens&gt;&gt;loop l_int:=to_number(regexp_substr(in_integers,in_pattern,1,l_pos));\nexit integer_tokens when l_int is null;l_result.extend;l_result(l_pos):= l_int;l_pos:=l_pos+1;\nend loop integer_tokens;return l_result;end to_int_table;end 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 style=\"color: #D4D4D4\"> function to_int_table(in_integers<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">varchar2<\/span><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 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\"> accessible<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">by(<\/span><span style=\"color: #569CD6\">package<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">the_api.math,package<\/span><span style=\"color: #D4D4D4\"> the_api.test_math)<\/span><span style=\"color: #569CD6\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #D4D4D4\"> sys<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">.ora_mining_number_nt:=sys.ora_mining_number_nt();<\/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 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: #569CD6\">begin<\/span><span style=\"color: #D4D4D4\">&lt;&lt;integer_tokens&gt;&gt;<\/span><span style=\"color: #C586C0\">loop<\/span><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: #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 style=\"color: #9CDCFE\">l_result<\/span><span style=\"color: #DCDCAA\">.extend<\/span><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 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: #C586C0\">end loop<\/span><span style=\"color: #D4D4D4\"> integer_tokens;<\/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 style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\"> to_int_table;<\/span><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<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\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\">syntax_error.sql<\/span><span role=\"button\" tabindex=\"0\" data-code=\"declare\n   l_var1  integer;\n   l_var2  varchar2(20);\nbegin\n   for r in \/*(*\/ select x.* from x join y on y.a = x.a)\n   loop\n      p(r.a, r.b, r.c);\n   end loop;\nend;\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\">declare<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #9CDCFE\">l_var1<\/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: #9CDCFE\">l_var2<\/span><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">varchar2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">20<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">begin<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> r <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #6A9955\">\/*(*\/<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> x.* <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> x <\/span><span style=\"color: #569CD6\">join<\/span><span style=\"color: #D4D4D4\"> y <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> y.a = x.a)<\/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\">      p(r.a, r.b, r.<\/span><span style=\"color: #569CD6\">c<\/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\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">end<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>I committed these files to my <a href=\"https:\/\/github.com\/PhilippSalvisberg\/sandbox\/tree\/main\/sqlcl\">sandbox GitHub repository<\/a>. This way I can compare the formatting results with the committed version and I can easily revert the changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running the Formatter with Default Settings<\/h2>\n\n\n\n<p>The following JavaScript queries all .sql files in a directory tree, applies the default formatter settings and replaces the original content with the formatted version.<\/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\">JavaScript<\/span><span role=\"button\" tabindex=\"0\" data-code=\"var getFiles = function (rootPath) {\n    var Collectors = Java.type(&quot;java.util.stream.Collectors&quot;);\n    var Files = Java.type(&quot;java.nio.file.Files&quot;);\n    var Paths = Java.type(&quot;java.nio.file.Paths&quot;);\n    var files = Files.walk(Paths.get(rootPath))\n        .filter(function (f) Files.isRegularFile(f) &amp;&amp; f.toString().endsWith(&quot;.sql&quot;))\n        .collect(Collectors.toList()); \n    return files;\n}\n\nif (args[1] == null) {\n    ctx.write(&quot;\\nplease provide the root path to a directory with .sql files.\\n\\n&quot;);\n} else {\n    ctx.write(&quot;\\n&quot;);\n    var Files = Java.type(&quot;java.nio.file.Files&quot;);\n    var files = getFiles(args[1]);\n    var Format = Java.type(&quot;oracle.dbtools.app.Format&quot;);\n    var formatter = new Format();\n    for (var i in files) {\n        ctx.write(&quot;Formatting file &quot; + (i+1) + &quot; of &quot; + files.length + &quot;: &quot; + files[i].toString() + &quot;... &quot;);\n        ctx.getOutputStream().flush();\n        var original = Files.readString(files[i]);\n        var result = formatter.format(original);\n        Files.writeString(files[i], result);\n        ctx.write(&quot;done.\\n&quot;);\n        ctx.getOutputStream().flush();\n    }\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\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">getFiles<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">rootPath<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Collectors<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Java<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">type<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;java.util.stream.Collectors&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Files<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Java<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">type<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;java.nio.file.Files&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Paths<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Java<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">type<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;java.nio.file.Paths&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">files<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Files<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">walk<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">Paths<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">rootPath<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        .<\/span><span style=\"color: #DCDCAA\">filter<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">Files<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">isRegularFile<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">) &amp;&amp; <\/span><span style=\"color: #DCDCAA\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toString<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">endsWith<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;.sql&quot;<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        .<\/span><span style=\"color: #DCDCAA\">collect<\/span><span style=\"color: #D4D4D4\">(Collectors.toList()); <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">files<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">args<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] == <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ctx.write(<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">please provide the root path to a directory with .sql files.<\/span><span style=\"color: #D7BA7D\">\\n\\n<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #9CDCFE\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">} else {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">    ctx.write(<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #9CDCFE\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">    var Files = Java.type(<\/span><span style=\"color: #CE9178\">&quot;java.nio.file.Files&quot;<\/span><span style=\"color: #9CDCFE\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">    var files = getFiles(args[1]);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">    var Format = Java.type(<\/span><span style=\"color: #CE9178\">&quot;oracle.dbtools.app.Format&quot;<\/span><span style=\"color: #9CDCFE\">);<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #9CDCFE\">    var formatter = new Format();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">    for (var i in files) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">        ctx.write(<\/span><span style=\"color: #CE9178\">&quot;Formatting file &quot;<\/span><span style=\"color: #9CDCFE\"> + (i+1) + <\/span><span style=\"color: #CE9178\">&quot; of &quot;<\/span><span style=\"color: #9CDCFE\"> + files.length + <\/span><span style=\"color: #CE9178\">&quot;: &quot;<\/span><span style=\"color: #9CDCFE\"> + files[i].toString() + <\/span><span style=\"color: #CE9178\">&quot;... &quot;<\/span><span style=\"color: #9CDCFE\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">        ctx.getOutputStream().flush();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">        var original = Files.readString(files[i]);<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #9CDCFE\">        var result = formatter.format(original);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">        Files.writeString(files[i], result);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">        ctx.write(<\/span><span style=\"color: #CE9178\">&quot;done.<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #9CDCFE\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">        ctx.getOutputStream().flush();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>SQLcl 20.2 uses the Nashorn JavaScript engine. This works also with Java 11. If you are interested in writing JavaScript scripts for SQLcl I recommend having a look at <a href=\"https:\/\/github.com\/mennooo\/SQLcl\">Menno Hoogendijk&#8217;s GitHub repo<\/a> and the examples in <a href=\"https:\/\/github.com\/oracle\/oracle-db-tools\/tree\/master\/sqlcl\/examples\">Oracle&#8217;s GitHub repo<\/a>.<\/p>\n\n\n\n<p>I&#8217;d like to focus in this blog post on the formatter. The formatter is instantiated with default settings on line 18. On line 23 the original file content is passed to the formatter and the formatted result is returned. The `ctx.getOutputStream().flush();` is a trick to force SQLcl to flush output on the console. This improves the user experience when processing a lot of files (see the video at the end of this blog post).<\/p>\n\n\n\n<p>You can store this JavaScript file along with the three example files in a directory of your choice. Then change to this directory and start SQLcl and execute the highlighted commands below (use <code>host dir<\/code> when you are using Windows):<\/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\">run default_format.js<\/span><span role=\"button\" tabindex=\"0\" data-code=\"sql \/nolog\n\nSQLcl: Release 20.2 Production on Sun Aug 09 16:16:19 2020\n\nCopyright (c) 1982, 2020, Oracle.  All rights reserved.\n\n\nSQL&gt; host ls\ndefault_format.js\tpackage_body.sql\tquery.sql\t\tsyntax_error.sql\n\nSQL&gt; script default_format.js\n\nplease provide the root path to a directory with .sql files.\n\nSQL&gt; script default_format.js .\n\nFormatting file 1 of 3: .\/query.sql... done.\nFormatting file 2 of 3: .\/syntax_error.sql... done.\nFormatting file 3 of 3: .\/package_body.sql... done.\nSQL&gt; \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: #DCDCAA\">sql<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">\/nolog<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">SQLcl:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">Release<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">20.2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">Production<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">on<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">Sun<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">Aug<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">09<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">16<\/span><span style=\"color: #CE9178\">:16:19<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">2020<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">Copyright<\/span><span style=\"color: #D4D4D4\"> (c) 1982, 2020, Oracle.  All rights reserved.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">SQL&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">host<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">ls<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">default_format.js<\/span><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #CE9178\">package_body.sql<\/span><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #CE9178\">query.sql<\/span><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #CE9178\">syntax_error.sql<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">SQL&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">script<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">default_format.js<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">please<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">provide<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">root<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">path<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">to<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">a<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">directory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">with<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">.sql<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">files.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">SQL&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">script<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">default_format.js<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">Formatting<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">file<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">of<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #CE9178\">:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">.\/query.sql...<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">done.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">Formatting<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">file<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">of<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #CE9178\">:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">.\/syntax_error.sql...<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">done.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">Formatting<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">file<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">of<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #CE9178\">:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">.\/package_body.sql...<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">done.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">SQL&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Here are the original and formatted versions side-by-side:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1323\" height=\"354\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_.png\" alt=\"\" class=\"wp-image-10404\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_.png 1323w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_-300x80.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_-1024x274.png 1024w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_-768x205.png 768w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_-260x70.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_-50x13.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_query.sql_-150x40.png 150w\" sizes=\"auto, (max-width:767px) 480px, (max-width:1323px) 100vw, 1323px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1319\" height=\"514\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_.png\" alt=\"\" class=\"wp-image-10407\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_.png 1319w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_-300x117.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_-1024x399.png 1024w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_-768x299.png 768w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_-260x101.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_-50x19.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_-150x58.png 150w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_package_body.sql_-1280x500.png 1280w\" sizes=\"auto, (max-width:767px) 480px, (max-width:1319px) 100vw, 1319px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1317\" height=\"258\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_.png\" alt=\"\" class=\"wp-image-10408\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_.png 1317w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_-300x59.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_-1024x201.png 1024w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_-768x150.png 768w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_-260x51.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_-50x10.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/default_formatted_syntax_error.sql_-150x29.png 150w\" sizes=\"auto, (max-width:767px) 480px, (max-width:1317px) 100vw, 1317px\" \/><\/a><\/figure>\n\n\n\n<p>The first two files are certainly easier to read now. However, the <code>syntax_error.sql<\/code> looks strange. The reason is, that the formatter is designed for interactive use and the SQL Developer team decided to format with a best effort approach, even if syntax errors are found. It&#8217;s important to note that a detected syntax error does not necessarily mean that the code is incorrect. It just means that the parser does not understand the code. This may happen due to bugs or because grammar changes are not (yet) supported by the parser.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Shortcomings to Address<\/h2>\n\n\n\n<p>You&#8217;ve seen that applying the formatter is quite easy. However, there are some shortcomings:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Files with syntax errors are formatted<\/strong><br \/>This may lead to a bad result and is typically unwanted when processing files in batch mode.<\/li>\n\n\n\n<li><strong>Only files with the file extension <code>.sql<\/code> are processed<\/strong><br \/>What about files with the extensions <code>.pks<\/code>, <code>.pkb<\/code>, <code>.vw<\/code>, etc.? They are not processed. A better default setting would be nice, along with an option to overwrite the file extensions to be processed.<\/li>\n\n\n\n<li><strong>Default <code>Advanced Format<\/code> settings only<\/strong><br \/>SQL Developer allows you to configure 26 formatter settings for typical coding styles. It would be nice, if the default setting could be changed in a similar way as in the SQL Developer&#8217;s preferences dialog.<\/li>\n\n\n\n<li><strong>Default <code>Custom Format<\/code> only<\/strong><br \/>If <code>Advanced Format<\/code> is not enough, you can configure the formatter further by writing your own Arbori program. However, it is not that easy and it is time-consuming to write and maintain an Arbori program. But if you happen to have such an Arbori program (as I do) then you&#8217;d like to use it as input for the formatter as well to get the very same result as in the SQL Developer IDE.<\/li>\n<\/ul>\n\n\n\n<p><em>You can use SQLcl&#8217;s <code>FORMAT FILE<\/code> command to address bullet points 1 and 3. However, it&#8217;s not possible to set <code>Custom Format<\/code> or to limit file extensions to be processed with <code>FORMAT FILE<\/code> in SQLcl 20.2. But you can pass a directory as <code>INPUT<\/code>&nbsp; and <code>OUTPUT<\/code> parameter (instead of file names). I tried that because it&#8217;s documented for <code>sdcli<\/code> (Thanks Torsten). So, if you do not need to limit file extensions or define a custom Arbori program, then the built-in <code>FORMAT FILE<\/code> is most probably good enough. [added on 2020-08-10]<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">More Complete Formatter CLI<\/h2>\n\n\n\n<p>I&#8217;ve provided a <a href=\"https:\/\/github.com\/Trivadis\/plsql-formatter-settings\/blob\/main\/sqlcl\/format.js\">format.js<\/a> as part of the <a href=\"https:\/\/github.com\/Trivadis\/plsql-formatter-settings\">Trivadis PL\/SQL &amp; SQL Formatter Settings<\/a>. I recommend downloading, cloning or forking this repository when you plan to use this script. It&#8217;s easier because the default Arbori program is referenced via a relative path and when you&#8217;re fine with it, you do not need to pass it as a command line argument. However, the <a href=\"https:\/\/github.com\/Trivadis\/plsql-formatter-settings\/blob\/main\/sqlcl\/format.js\">format.js<\/a> works also as a standalone script.<\/p>\n\n\n\n<p>In my environment, I start the script as follows:<\/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\">run format.js<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SQL&gt; script ..\/..\/Trivadis\/plsql-formatter-settings\/sqlcl\/format.js\n\nformat.js for SQLcl 20.2\nCopyright 2020 by Philipp Salvisberg (philipp.salvisberg@trivadis.com)\n\nmissing mandatory <rootPath&gt; argument.\n\nusage: script format.js <rootPath&gt; [options]\n\nmandatory arguments:\n  <rootPath&gt;     path to directory containing files to format (content will be replaced!)\n\noptions:\n  ext=<ext&gt;      comma separated list of file extensions to process, e.g. ext=sql,pks,pkb\n  arbori=<file&gt;  path to the file containing the Arbori program for custom format settings\n\nSQL&gt;\" 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 cbp-line-highlight\"><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">&gt; script ..\/..\/Trivadis\/plsql-formatter-settings\/sqlcl\/format.js<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">format.js <\/span><span style=\"color: #569CD6\">for<\/span><span style=\"color: #D4D4D4\"> SQLcl <\/span><span style=\"color: #B5CEA8\">20<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #B5CEA8\">2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Copyright <\/span><span style=\"color: #B5CEA8\">2020<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">by<\/span><span style=\"color: #D4D4D4\"> Philipp Salvisberg (philipp.salvisberg@trivadis.com)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">missing mandatory &lt;rootPath&gt; argument.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">usage: script format.js &lt;rootPath&gt; [options]<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">mandatory arguments:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">  &lt;rootPath&gt;     <\/span><span style=\"color: #569CD6\">path<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">to<\/span><span style=\"color: #D4D4D4\"> directory containing files <\/span><span style=\"color: #569CD6\">to<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">format<\/span><span style=\"color: #D4D4D4\"> (content will be replaced!)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">options:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">  ext=&lt;ext&gt;      comma separated list of <\/span><span style=\"color: #569CD6\">file<\/span><span style=\"color: #D4D4D4\"> extensions <\/span><span style=\"color: #569CD6\">to<\/span><span style=\"color: #D4D4D4\"> process, e.g. ext=<\/span><span style=\"color: #569CD6\">sql<\/span><span style=\"color: #D4D4D4\">,pks,pkb<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">  arbori=&lt;<\/span><span style=\"color: #569CD6\">file<\/span><span style=\"color: #D4D4D4\">&gt;  <\/span><span style=\"color: #569CD6\">path<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">to<\/span><span style=\"color: #D4D4D4\"> the <\/span><span style=\"color: #569CD6\">file<\/span><span style=\"color: #D4D4D4\"> containing the Arbori program <\/span><span style=\"color: #569CD6\">for<\/span><span style=\"color: #D4D4D4\"> custom format settings<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>As in the simplified version an error is shown with a short help on how to use this CLI. So, I need to pass a path, e.g. <code>.<\/code> for the current directory, to make it work.<\/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\">run format.js with path<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SQL&gt; script ..\/..\/Trivadis\/plsql-formatter-settings\/sqlcl\/format.js .\n\nformat.js for SQLcl 20.2\nCopyright 2020 by Philipp Salvisberg (philipp.salvisberg@trivadis.com)\n\nFormatting file 1 of 3: .\/query.sql... done.\nFormatting file 2 of 3: .\/syntax_error.sql... Syntax Error at line 4, column 12\n\n\n   for r in \/*(*\/ select x.* from x join y on y.a = x.a)\n            ^^^                                          \n\nExpected: name_wo_function_call,identifier,term,factor,name,. skipped.\nFormatting file 3 of 3: .\/package_body.sql... done.\nSQL&gt; \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 cbp-line-highlight\"><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">&gt; script ..\/..\/Trivadis\/plsql-formatter-settings\/sqlcl\/format.js .<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">format.js <\/span><span style=\"color: #569CD6\">for<\/span><span style=\"color: #D4D4D4\"> SQLcl <\/span><span style=\"color: #B5CEA8\">20<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #B5CEA8\">2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Copyright <\/span><span style=\"color: #B5CEA8\">2020<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">by<\/span><span style=\"color: #D4D4D4\"> Philipp Salvisberg (philipp.salvisberg@trivadis.com)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Formatting <\/span><span style=\"color: #569CD6\">file<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> of <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">: .\/query.sql... done.<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">Formatting <\/span><span style=\"color: #569CD6\">file<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\"> of <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">: .\/syntax_error.sql... Syntax Error <\/span><span style=\"color: #569CD6\">at<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">line<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, column <\/span><span style=\"color: #B5CEA8\">12<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">for<\/span><span style=\"color: #D4D4D4\"> r <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #6A9955\">\/*(*\/<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> x.* <\/span><span style=\"color: #569CD6\">from<\/span><span style=\"color: #D4D4D4\"> x <\/span><span style=\"color: #569CD6\">join<\/span><span style=\"color: #D4D4D4\"> y <\/span><span style=\"color: #569CD6\">on<\/span><span style=\"color: #D4D4D4\"> y.a = x.a)<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">            ^^^                                          <\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">Expected: name_wo_function_call,identifier,term,factor,<\/span><span style=\"color: #569CD6\">name<\/span><span style=\"color: #D4D4D4\">,. skipped.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Formatting <\/span><span style=\"color: #569CD6\">file<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\"> of <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">: .\/package_body.sql... done.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-d-4-d-4-d-4-color has-text-color has-875-rem-font-size\">As you see in the console output, there was an error when processing the second file <code>syntax_error.sql<\/code>. The syntax error was detected, the error reported and the file was left unchanged. Behind the scenes, different formatter settings have been applied. See the <a href=\"https:\/\/github.com\/Trivadis\/plsql-formatter-settings\/blob\/main\/sqlcl\/format.js\">source code<\/a> for details. It should be quite self-explanatory.<\/p>\n\n\n\n<p>These are the formatting results:<\/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\">query.sql &#8211; custom format result<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SELECT d.department_name,\n       v.employee_id,\n       v.last_name\n  FROM departments d CROSS APPLY (\n          SELECT *\n            FROM employees e\n           WHERE e.department_id = d.department_id\n       ) v\n WHERE d.department_name IN (\n          'Marketing',\n          'Operations',\n          'Public Relations'\n       )\n ORDER BY d.department_name,\n          v.employee_id;\" 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\"> d.department_name,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       v.employee_id,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       v.last_name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> departments d <\/span><span style=\"color: #569CD6\">CROSS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">APPLY<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> *<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> employees e<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           <\/span><span style=\"color: #569CD6\">WHERE<\/span><span style=\"color: #D4D4D4\"> e.department_id = d.department_id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       ) v<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">WHERE<\/span><span style=\"color: #D4D4D4\"> d.department_name <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #CE9178\">&#39;Marketing&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #CE9178\">&#39;Operations&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #CE9178\">&#39;Public Relations&#39;<\/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\">ORDER BY<\/span><span style=\"color: #D4D4D4\"> d.department_name,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          v.employee_id;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\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\">package_body.sql &#8211; custom format result<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE BODY the_api.math AS\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\n      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<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">OR<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">REPLACE<\/span><span style=\"color: #D4D4D4\"> PACKAGE BODY the_api.math <\/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\"> to_int_table (<\/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: #569CD6\">RETURN<\/span><span style=\"color: #D4D4D4\"> sys.ora_mining_number_nt<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      DETERMINISTIC<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ACCESSIBLE <\/span><span style=\"color: #569CD6\">BY<\/span><span style=\"color: #D4D4D4\"> ( PACKAGE the_api.math, PACKAGE 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\">      l_result  sys.ora_mining_number_nt := sys.ora_mining_number_nt();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      l_pos     <\/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\">      l_int     <\/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: #569CD6\">LOOP<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         l_int               := to_number(regexp_substr(in_integers, in_pattern, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, l_pos));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         EXIT integer_tokens <\/span><span style=\"color: #569CD6\">WHEN<\/span><span style=\"color: #D4D4D4\"> l_int <\/span><span style=\"color: #569CD6\">IS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">NULL<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         l_result.extend;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         l_result(l_pos)     := l_int;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         l_pos               := l_pos + <\/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: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">LOOP<\/span><span style=\"color: #D4D4D4\"> integer_tokens;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">RETURN<\/span><span style=\"color: #D4D4D4\"> l_result;<\/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>And here&#8217;s a short audio-less video, showing how format.js is used to format utPLSQL packages and types.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/sqlcl_formatter.mp4\"><\/video><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>Formatting SQL scripts with SQLcl is quite easy when you&#8217;re okay with the default formatter settings. It&#8217;s more work when you want to apply advanced and custom format settings with some sanity checks. Nonetheless parsing the SQL script and reporting error messages was only 14 lines of code. Formatting is possible without an active connection to the database. As long as the grammar is correct, the formatting result should be good. You can imagine what you could do when accessing the database as well (e.g. to process the source stored in the database). This clearly shows the power of JavaScript within SQLcl.<\/p>\n\n\n\n<p>When you have questions regarding SQL Developer&#8217;s default formatting behaviour then I suggest asking them in the <a href=\"https:\/\/community.oracle.com\/community\/groundbreakers\/database\/developer-tools\/sql_developer\">SQL Developer&#8217;s forum<\/a>. When you find strange formatting results for the Trivadis PL\/SQL &amp; SQL formatter settings or the format.js script then please <a href=\"https:\/\/github.com\/Trivadis\/plsql-formatter-settings#issues\">open an issue in this GitHub repo<\/a>. Thank you.<\/p>\n\n\n\n<p><em>Updated on 2020-08-10, added a section in the &#8220;Shortcomings to Address&#8221; chapter regarding the <code>FORMAT FILE<\/code> command in SQLcl. HT to Torsten Kleiber.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Oracle&#8217;s SQL Developer can format code in any worksheet and PL\/SQL editor. The formatter is highly configurable and the default formatting results are becoming better with every version. Oracle&#8217;s SQLcl is a command-line tool. It&#8217;s a stripped-down version of SQL Developer and is known as a user-friendly alternative for SQL*Plus. But<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":10426,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[129,135,13,85,87,126],"class_list":["post-10395","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-arbori","tag-javascript","tag-plsql","tag-sql","tag-sql-developer","tag-sqlcl"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Formatting SQL Scripts in a Directory Tree with SQLcl - Philipp Salvisberg&#039;s Blog<\/title>\n<meta name=\"description\" content=\"Oracle&#039;s SQLcl is a stripped down version of SQL Developer. You can use it to format your SQL scripts with a few lines of JavaScript.\" \/>\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\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Formatting SQL Scripts in a Directory Tree with SQLcl - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"Oracle&#039;s SQLcl is a stripped down version of SQL Developer. You can use it to format your SQL scripts with a few lines of JavaScript.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-08-09T18:42:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-12T12:51:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/sqlcl.png\" \/>\n\t<meta property=\"og:image:width\" content=\"728\" \/>\n\t<meta property=\"og:image:height\" content=\"624\" \/>\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=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"Formatting SQL Scripts in a Directory Tree with SQLcl\",\"datePublished\":\"2020-08-09T18:42:32+00:00\",\"dateModified\":\"2023-11-12T12:51:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/\"},\"wordCount\":1171,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/sqlcl.png\",\"keywords\":[\"Arbori\",\"JavaScript\",\"PL\\\/SQL\",\"SQL\",\"SQL Developer\",\"SQLcl\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/\",\"name\":\"Formatting SQL Scripts in a Directory Tree with SQLcl - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/sqlcl.png\",\"datePublished\":\"2020-08-09T18:42:32+00:00\",\"dateModified\":\"2023-11-12T12:51:37+00:00\",\"description\":\"Oracle's SQLcl is a stripped down version of SQL Developer. You can use it to format your SQL scripts with a few lines of JavaScript.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/sqlcl.png\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/sqlcl.png\",\"width\":728,\"height\":624},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/08\\\/09\\\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Formatting SQL Scripts in a Directory Tree with SQLcl\"}]},{\"@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":"Formatting SQL Scripts in a Directory Tree with SQLcl - Philipp Salvisberg&#039;s Blog","description":"Oracle's SQLcl is a stripped down version of SQL Developer. You can use it to format your SQL scripts with a few lines of JavaScript.","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\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/","og_locale":"en_US","og_type":"article","og_title":"Formatting SQL Scripts in a Directory Tree with SQLcl - Philipp Salvisberg&#039;s Blog","og_description":"Oracle's SQLcl is a stripped down version of SQL Developer. You can use it to format your SQL scripts with a few lines of JavaScript.","og_url":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2020-08-09T18:42:32+00:00","article_modified_time":"2023-11-12T12:51:37+00:00","og_image":[{"width":728,"height":624,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/sqlcl.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":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"Formatting SQL Scripts in a Directory Tree with SQLcl","datePublished":"2020-08-09T18:42:32+00:00","dateModified":"2023-11-12T12:51:37+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/"},"wordCount":1171,"commentCount":4,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/sqlcl.png","keywords":["Arbori","JavaScript","PL\/SQL","SQL","SQL Developer","SQLcl"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/","url":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/","name":"Formatting SQL Scripts in a Directory Tree with SQLcl - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/sqlcl.png","datePublished":"2020-08-09T18:42:32+00:00","dateModified":"2023-11-12T12:51:37+00:00","description":"Oracle's SQLcl is a stripped down version of SQL Developer. You can use it to format your SQL scripts with a few lines of JavaScript.","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/sqlcl.png","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/08\/sqlcl.png","width":728,"height":624},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2020\/08\/09\/formatting-sql-scripts-in-a-directory-tree-with-sqlcl\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Formatting SQL Scripts in a Directory Tree with SQLcl"}]},{"@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\/10395","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=10395"}],"version-history":[{"count":46,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/10395\/revisions"}],"predecessor-version":[{"id":12757,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/10395\/revisions\/12757"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/10426"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=10395"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=10395"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=10395"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}