{"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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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 class=\"wp-block-paragraph\">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":28,"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 v28.8 (Yoast SEO v28.8) - 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=\"Open source Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Open source Team\" \/>\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\":\"Open source Team\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/4bae5e5dd8c7d48edbd948772b49b202\"},\"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\\\/4bae5e5dd8c7d48edbd948772b49b202\"},\"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\\\/4bae5e5dd8c7d48edbd948772b49b202\",\"name\":\"Open source Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g\",\"caption\":\"Open source Team\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/open-source-team\\\/\"}]}<\/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":"Open source Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Open source Team","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":"Open source Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4bae5e5dd8c7d48edbd948772b49b202"},"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\/4bae5e5dd8c7d48edbd948772b49b202"},"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\/4bae5e5dd8c7d48edbd948772b49b202","name":"Open source Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g","caption":"Open source Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/open-source-team\/"}]}},"_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\/28"}],"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}]}}