{"id":20943,"date":"2022-12-09T16:43:34","date_gmt":"2022-12-09T15:43:34","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=20943"},"modified":"2022-12-09T16:43:35","modified_gmt":"2022-12-09T15:43:35","slug":"improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/","title":{"rendered":"Improve your development experience in PostgreSQL&#8217;s PL\/pgSQL by using plpgsql_check"},"content":{"rendered":"\n<p>In the <a href=\"https:\/\/www.dbi-services.com\/blog\/some-tips-when-developing-in-postgresqls-pl-pgsql\/\" target=\"_blank\" rel=\"noreferrer noopener\">last post <\/a>we&#8217;ve highlighted some tips when developing functions and\/or procedures in PostgreSQL&#8217;s PL\/pgSQL. Especially the Compile-Time and Run-Time checks can save you a lot of work and give you important hints while developing your code. But still, at least when compared to other languages, the possibilities for debugging your code in PL\/pgSQL are quite limited in vanilla PostgreSQL. Once more, extension to the rescue: There are plenty of extensions out there, and some of them are targeting the development experience with PL\/pgSQL. In this post we&#8217;ll look at <a href=\"https:\/\/github.com\/okbob\/plpgsql_check\" target=\"_blank\" rel=\"noreferrer noopener\">plpgsql_check<\/a>. <\/p>\n\n\n\n<p>Standard warning: When it comes to extensions outside of PostgreSQL core, always make sure that the extension you want to use is actively maintained. This is not an issue for <a href=\"https:\/\/github.com\/okbob\/plpgsql_check\" target=\"_blank\" rel=\"noreferrer noopener\">plpgsql_check<\/a>, but it might be for others. If is not maintained anymore, either maintain it on your own or look for other solutions for your requirement.<\/p>\n\n\n\n<p>Getting plpgsql_check onto the system is straight forward (I am using the current development version here, please use a version from the <a href=\"https:\/\/github.com\/okbob\/plpgsql_check\/releases\/\" target=\"_blank\" rel=\"noreferrer noopener\">release<\/a> page for real systems):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\npostgres@debian11pg:\/home\/postgres\/ &#x5B;150] git clone https:\/\/github.com\/okbob\/plpgsql_check.git\npostgres@debian11pg:\/home\/postgres\/ &#x5B;150] cd plpgsql_check\/\npostgres@debian11pg:\/home\/postgres\/plpgsql_check\/ &#x5B;150] make USE_PGXS=1 clean\npostgres@debian11pg:\/home\/postgres\/plpgsql_check\/ &#x5B;150] make USE_PGXS=1 install\n\n<\/pre><\/div>\n\n\n<p>From there on it is the standard way for installing extensions:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\npostgres@debian11pg:\/home\/postgres\/plpgsql_check\/ &#x5B;150] psql\npsql (15.0 dbi services build)\nType &quot;help&quot; for help.\n\npostgres=# select * from pg_available_extensions where name like &#039;%check%&#039;;\n     name      | default_version | installed_version |                  comment                   \n---------------+-----------------+-------------------+--------------------------------------------\n amcheck       | 1.3             |                   | functions for verifying relation integrity\n plpgsql_check | 2.2             |                   | extended check for plpgsql functions\n(2 rows)\n\npostgres=# create extension plpgsql_check;\nCREATE EXTENSION\npostgres=# \\dx\n                        List of installed extensions\n     Name      | Version |   Schema   |             Description              \n---------------+---------+------------+--------------------------------------\n plpgsql       | 1.0     | pg_catalog | PL\/pgSQL procedural language\n plpgsql_check | 2.2     | public     | extended check for plpgsql functions\n(2 rows)\n\npostgres=# \n<\/pre><\/div>\n\n\n<p>What can we do with it? Suppose the following table and function:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\npostgres=# create table t ( a int, b int );\nCREATE TABLE\npostgres=# create function f1() returns int as\npostgres-# $$\npostgres$# begin\npostgres$#   select c from t limit 1;\npostgres$# end; $$ language plpgsql;\nCREATE FUNCTION\n<\/pre><\/div>\n\n\n<p>As there is no column &#8220;c&#8221; this for sure fails during execution:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\npostgres=# select f1();\nERROR:  column &quot;c&quot; does not exist\nLINE 1: select c from t limit 1\n               ^\nQUERY:  select c from t limit 1\nCONTEXT:  PL\/pgSQL function f1() line 3 at SQL statement\n<\/pre><\/div>\n\n\n<p>Using the extension we can catch such kind of issues before it fails later on in production:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\npostgres=# select * from plpgsql_check_function_tb(&#039;f1()&#039;);\n functionid | lineno |   statement   | sqlstate |          message          | detail | hint | level | position |          query          | context \n------------+--------+---------------+----------+---------------------------+--------+------+-------+----------+-------------------------+---------\n f1         |      3 | SQL statement | 42703    | column &quot;c&quot; does not exist |        |      | error |        8 | select c from t limit 1 | \n(1 row)\n<\/pre><\/div>\n\n\n<p>Another example is this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\npostgres=# create or replace function f1() returns int as\n$$\nbegin\n  select b from t;\nend; $$ language plpgsql;\nCREATE FUNCTION\npostgres=# select * from plpgsql_check_function_tb(&#039;f1()&#039;);\n functionid | lineno |   statement   | sqlstate |                 message                  | detail | hint | level | position | query | context \n------------+--------+---------------+----------+------------------------------------------+--------+------+-------+----------+-------+---------\n f1         |      3 | SQL statement | 42601    | query has no destination for result data |        |      | error |          |       | \n(1 row)\n\npostgres=# \n<\/pre><\/div>\n\n\n<p>Or this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\npostgres=# create or replace function f1() returns int as\n$$\ndeclare\n  i int;\nbegin\n  select b into i from t;\nend; $$ language plpgsql;\nCREATE FUNCTION\npostgres=# select * from plpgsql_check_function_tb(&#039;f1()&#039;);\n functionid | lineno | statement | sqlstate |                    message                     | detail | hint |     level     | position | query | context \n------------+--------+-----------+----------+------------------------------------------------+--------+------+---------------+----------+-------+---------\n f1         |        |           | 2F005    | control reached end of function without RETURN |        |      | error         |          |       | \n f1         |      3 | DECLARE   | 00000    | never read variable &quot;i&quot;                        |        |      | warning extra |          |       | \n(2 rows)\n<\/pre><\/div>\n\n\n<p>There also is a profiler which gives you more information where time is spend inside your functions or procedures. Here is a function which does some real (but stupid) work:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\npostgres=# insert into t select i, i from generate_series(1,1000000) i;\nINSERT 0 1000000\npostgres=# create or replace function f1() returns int as\n$$\ndeclare\n  r record;\n  i int;\n  j int := 0;\nbegin\n  for r in select a from t\n  loop\n    i := r.a;\n  end loop;\n  for i in 1..1000000\n  loop\n    j := j + 1;\n  end loop;\n  return i;\nend; $$ language plpgsql;\nCREATE FUNCTION\n<\/pre><\/div>\n\n\n<p>First, lets confirm we do not have any issues which plpgsql_check is able to detect:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\npostgres=# select * from plpgsql_check_function_tb(&#039;f1()&#039;);\n functionid | lineno | statement | sqlstate | message | detail | hint | level | position | query | context \n------------+--------+-----------+----------+---------+--------+------+-------+----------+-------+---------\n(0 rows)\n<\/pre><\/div>\n\n\n<p>Fine, now lets check how time is spend inside the function:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\npostgres=# set plpgsql_check.profiler to on;\nSET\npostgres=# select * from f1();\n   f1    \n---------\n 1000000\n(1 row)\n\npostgres=# select * from plpgsql_profiler_function_tb(&#039;f1()&#039;);\n lineno | stmt_lineno |        queryids        | cmds_on_row | exec_stmts | exec_stmts_err | total_time | avg_time | max_time  | processed_rows |           source           \n--------+-------------+------------------------+-------------+------------+----------------+------------+----------+-----------+----------------+----------------------------\n      1 |             |                        |             |            |                |            |          |           |                | \n      2 |             |                        |             |            |                |            |          |           |                | declare\n      3 |             |                        |             |            |                |            |          |           |                |   r record;\n      4 |             |                        |             |            |                |            |          |           |                |   i int;\n      5 |             |                        |             |            |                |            |          |           |                |   j int := 0;\n      6 |           6 |                        |           1 |          1 |              0 |      0.009 |    0.009 | {356.329} | {0}            | begin\n      7 |           7 | {5244141801870714068}  |           1 |          1 |              0 |    159.998 |  159.998 | {249.678} | {0}            |   for r in select a from t\n      8 |             |                        |             |            |                |            |          |           |                |   loop\n      9 |           9 | {4704117640272101272}  |           1 |    1000002 |              0 |      89.68 |    0.001 | {0.236}   | {0}            |     i := r.a;\n     10 |             |                        |             |            |                |            |          |           |                |   end loop;\n     11 |          11 |                        |           1 |          1 |              0 |     41.715 |   41.715 | {106.642} | {0}            |   for i in 1..1000000\n     12 |             |                        |             |            |                |            |          |           |                |   loop\n     13 |          13 | {-8156123798940658127} |           1 |    1000000 |              0 |     64.927 |    0.001 | {0.021}   | {0}            |     j := j + 1;\n     14 |             |                        |             |            |                |            |          |           |                |   end loop;\n     15 |          15 |                        |           1 |          1 |              0 |          0 |        0 | {0}       | {0}            |   return i;\n     16 |             |                        |             |            |                |            |          |           |                | end; \n(16 rows)\n\npostgres=# select * from plpgsql_profiler_function_statements_tb(&#039;f1()&#039;);\n stmtid | parent_stmtid | parent_note | block_num | lineno |       queryid        | exec_stmts | exec_stmts_err | total_time | avg_time | max_time | processed_rows |            stmtname            \n--------+---------------+-------------+-----------+--------+----------------------+------------+----------------+------------+----------+----------+----------------+--------------------------------\n      0 |               |             |         1 |      6 |                      |          1 |              0 |      0.009 |    0.009 |  356.329 |              0 | statement block\n      1 |             0 | body        |         1 |      7 |  5244141801870714068 |          1 |              0 |    159.998 |  159.998 |  249.678 |              0 | FOR over SELECT rows\n      2 |             1 | loop body   |         1 |      9 |  4704117640272101272 |    1000002 |              0 |      89.68 |    0.001 |    0.236 |              0 | assignment\n      3 |             0 | body        |         2 |     11 |                      |          1 |              0 |     41.715 |   41.715 |  106.642 |              0 | FOR with integer loop variable\n      4 |             3 | loop body   |         1 |     13 | -8156123798940658127 |    1000000 |              0 |     64.927 |    0.001 |    0.021 |              0 | assignment\n      5 |             0 | body        |         3 |     15 |                      |          1 |              0 |          0 |        0 |        0 |              0 | RETURN\n\n<\/pre><\/div>\n\n\n<p>Really nice. This was only about the basics, there is much more information on the <a href=\"https:\/\/github.com\/okbob\/plpgsql_check\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub<\/a> page or on Pavel&#8217;s blog, e.g. <a href=\"https:\/\/okbob.blogspot.com\/2019\/08\/why-you-need-plpgsqlcheck-if-you-write.html\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last post we&#8217;ve highlighted some tips when developing functions and\/or procedures in PostgreSQL&#8217;s PL\/pgSQL. Especially the Compile-Time and Run-Time checks can save you a lot of work and give you important hints while developing your code. But still, at least when compared to other languages, the possibilities for debugging your code in PL\/pgSQL [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[229,198,368],"tags":[2602],"type_dbi":[],"class_list":["post-20943","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","category-database-management","category-development-performance","tag-postgresql-2"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Improve your development experience in PostgreSQL&#039;s PL\/pgSQL by using plpgsql_check - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Improve your development experience in PostgreSQL&#039;s PL\/pgSQL by using plpgsql_check\" \/>\n<meta property=\"og:description\" content=\"In the last post we&#8217;ve highlighted some tips when developing functions and\/or procedures in PostgreSQL&#8217;s PL\/pgSQL. Especially the Compile-Time and Run-Time checks can save you a lot of work and give you important hints while developing your code. But still, at least when compared to other languages, the possibilities for debugging your code in PL\/pgSQL [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-12-09T15:43:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-12-09T15:43:35+00:00\" \/>\n<meta name=\"author\" content=\"Daniel Westermann\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@westermanndanie\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daniel Westermann\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/\"},\"author\":{\"name\":\"Daniel Westermann\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"headline\":\"Improve your development experience in PostgreSQL&#8217;s PL\/pgSQL by using plpgsql_check\",\"datePublished\":\"2022-12-09T15:43:34+00:00\",\"dateModified\":\"2022-12-09T15:43:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/\"},\"wordCount\":338,\"commentCount\":0,\"keywords\":[\"postgresql\"],\"articleSection\":[\"Database Administration &amp; Monitoring\",\"Database management\",\"Development &amp; Performance\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/\",\"name\":\"Improve your development experience in PostgreSQL's PL\/pgSQL by using plpgsql_check - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2022-12-09T15:43:34+00:00\",\"dateModified\":\"2022-12-09T15:43:35+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Improve your development experience in PostgreSQL&#8217;s PL\/pgSQL by using plpgsql_check\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\",\"name\":\"Daniel Westermann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"caption\":\"Daniel Westermann\"},\"description\":\"Daniel Westermann is Principal Consultant and Technology Leader Open Infrastructure at dbi services. He has more than 15 years of experience in management, engineering and optimization of databases and infrastructures, especially on Oracle and PostgreSQL. Since the beginning of his career, he has specialized in Oracle Technologies and is Oracle Certified Professional 12c and Oracle Certified Expert RAC\/GridInfra. Over time, Daniel has become increasingly interested in open source technologies, becoming \u201cTechnology Leader Open Infrastructure\u201d and PostgreSQL expert. \u00a0Based on community or EnterpriseDB tools, he develops and installs complex high available solutions with PostgreSQL. He is also a certified PostgreSQL Plus 9.0 Professional and a Postgres Advanced Server 9.4 Professional. He is a regular speaker at PostgreSQL conferences in Switzerland and Europe. Today Daniel is also supporting our customers on AWS services such as AWS RDS, database migrations into the cloud, EC2 and automated infrastructure management with AWS SSM (System Manager). He is a certified AWS Solutions Architect Professional. Prior to dbi services, Daniel was Management System Engineer at LC SYSTEMS-Engineering AG in Basel. Before that, he worked as Oracle Developper &amp;\u00a0Project Manager at Delta Energy Solutions AG in Basel (today Powel AG). Daniel holds a diploma in Business Informatics (DHBW, Germany). His branch-related experience mainly covers the pharma industry, the financial sector, energy, lottery and telecommunications.\",\"sameAs\":[\"https:\/\/x.com\/westermanndanie\"],\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/daniel-westermann\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Improve your development experience in PostgreSQL's PL\/pgSQL by using plpgsql_check - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/","og_locale":"en_US","og_type":"article","og_title":"Improve your development experience in PostgreSQL's PL\/pgSQL by using plpgsql_check","og_description":"In the last post we&#8217;ve highlighted some tips when developing functions and\/or procedures in PostgreSQL&#8217;s PL\/pgSQL. Especially the Compile-Time and Run-Time checks can save you a lot of work and give you important hints while developing your code. But still, at least when compared to other languages, the possibilities for debugging your code in PL\/pgSQL [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/","og_site_name":"dbi Blog","article_published_time":"2022-12-09T15:43:34+00:00","article_modified_time":"2022-12-09T15:43:35+00:00","author":"Daniel Westermann","twitter_card":"summary_large_image","twitter_creator":"@westermanndanie","twitter_misc":{"Written by":"Daniel Westermann","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/"},"author":{"name":"Daniel Westermann","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"headline":"Improve your development experience in PostgreSQL&#8217;s PL\/pgSQL by using plpgsql_check","datePublished":"2022-12-09T15:43:34+00:00","dateModified":"2022-12-09T15:43:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/"},"wordCount":338,"commentCount":0,"keywords":["postgresql"],"articleSection":["Database Administration &amp; Monitoring","Database management","Development &amp; Performance"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/","url":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/","name":"Improve your development experience in PostgreSQL's PL\/pgSQL by using plpgsql_check - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2022-12-09T15:43:34+00:00","dateModified":"2022-12-09T15:43:35+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/improve-your-development-experience-in-postgresqls-pl-pgsql-by-using-plpgsql_check\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Improve your development experience in PostgreSQL&#8217;s PL\/pgSQL by using plpgsql_check"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66","name":"Daniel Westermann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","caption":"Daniel Westermann"},"description":"Daniel Westermann is Principal Consultant and Technology Leader Open Infrastructure at dbi services. He has more than 15 years of experience in management, engineering and optimization of databases and infrastructures, especially on Oracle and PostgreSQL. Since the beginning of his career, he has specialized in Oracle Technologies and is Oracle Certified Professional 12c and Oracle Certified Expert RAC\/GridInfra. Over time, Daniel has become increasingly interested in open source technologies, becoming \u201cTechnology Leader Open Infrastructure\u201d and PostgreSQL expert. \u00a0Based on community or EnterpriseDB tools, he develops and installs complex high available solutions with PostgreSQL. He is also a certified PostgreSQL Plus 9.0 Professional and a Postgres Advanced Server 9.4 Professional. He is a regular speaker at PostgreSQL conferences in Switzerland and Europe. Today Daniel is also supporting our customers on AWS services such as AWS RDS, database migrations into the cloud, EC2 and automated infrastructure management with AWS SSM (System Manager). He is a certified AWS Solutions Architect Professional. Prior to dbi services, Daniel was Management System Engineer at LC SYSTEMS-Engineering AG in Basel. Before that, he worked as Oracle Developper &amp;\u00a0Project Manager at Delta Energy Solutions AG in Basel (today Powel AG). Daniel holds a diploma in Business Informatics (DHBW, Germany). His branch-related experience mainly covers the pharma industry, the financial sector, energy, lottery and telecommunications.","sameAs":["https:\/\/x.com\/westermanndanie"],"url":"https:\/\/www.dbi-services.com\/blog\/author\/daniel-westermann\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/20943","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=20943"}],"version-history":[{"count":9,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/20943\/revisions"}],"predecessor-version":[{"id":20993,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/20943\/revisions\/20993"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=20943"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=20943"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=20943"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=20943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}