{"id":65315,"date":"2024-01-18T15:52:35","date_gmt":"2024-01-18T15:52:35","guid":{"rendered":"https:\/\/arquiconsult.com\/?p=65315"},"modified":"2024-10-23T10:35:11","modified_gmt":"2024-10-23T09:35:11","slug":"bc-extension-records-manipulation-on-installing-apps","status":"publish","type":"post","link":"https:\/\/arquiconsult.com\/en\/bc-extension-records-manipulation-on-installing-apps\/","title":{"rendered":"#045 BC EXTENSION RECORDS MANIPULATION ON INSTALLING APPS"},"content":{"rendered":"<div class=\"services_vertical horizontal_services row\" style=\"background-color: #f7f7f7; padding: 25px; border-radius: 5px; text-align: justify;\">\n<p style=\"text-align: left;\">Every table extension in Business Central corresponds to a different table in SQL database.<\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: left;\"><strong>For example:<\/strong><\/p>\n<table class=\" alignleft\" width=\"100%\">\n<tbody>\n<tr>\n<td width=\"47%\"><strong>Customer table in SQL from the Base App<\/strong><\/td>\n<td width=\"52%\"><strong>Customer extension table in SQL from the other app<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"47%\">No.<\/td>\n<td width=\"52%\">No.<\/td>\n<\/tr>\n<tr>\n<td width=\"47%\">Name<\/td>\n<td width=\"52%\">QQQ Field 1<\/td>\n<\/tr>\n<tr>\n<td width=\"47%\">Address<\/td>\n<td width=\"52%\">QQQ Field 2<\/td>\n<\/tr>\n<tr>\n<td width=\"47%\">Address 2<\/td>\n<td width=\"52%\"><\/td>\n<\/tr>\n<tr>\n<td width=\"47%\">Post Code<\/td>\n<td width=\"52%\"><\/td>\n<\/tr>\n<tr>\n<td width=\"47%\">\u2026<\/td>\n<td width=\"52%\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"text-align: left;\">When installing an app with table extensions, a delete and insert command is executed for each table extension of the app being installed.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: left;\"><strong>Why does this happen?<\/strong><\/p>\n<p style=\"text-align: left;\">This information is valid for BC21 and BC22.<\/p>\n<p style=\"text-align: left;\">Other versions may exhibit different behavior, but with similar effects.<\/p>\n<p style=\"text-align: left;\">When installing an app with table extensions, SQL commands like the following will be executed. This syntax has been simplified for better readability.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: left;\"><strong>&#8212; DELETE FROM Extension Table if it doesn\u2019t exist in the Base App.<\/strong><\/p>\n<p style=\"text-align: left;\">DELETE FROM &lt; company &gt;$&lt; table &gt;$QQQAppGUID<\/p>\n<p style=\"text-align: left;\">WHERE NOT EXISTS<\/p>\n<p>(<\/p>\n<p>SELECT 1<\/p>\n<p>FROM &lt; company &gt;$&lt; table &gt;$BaseAppGUID<\/p>\n<p>WHERE<\/p>\n<p>&lt; company &gt;$&lt; table &gt;$QQQAppGUID.&lt; PK &gt; = &lt; company &gt;$&lt; table &gt;$BaseAppGUID.&lt; PK &gt;<\/p>\n<p>)<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: left;\"><strong>&#8212; INSERT INTO Extension Table to match the same rows of the base app.<\/strong><\/p>\n<p style=\"text-align: left;\">INSERT INTO &lt; company &gt;$&lt; table &gt;$QQQAppGUID (&lt; PK &gt;, QQQAppColumns)<\/p>\n<p style=\"text-align: left;\">SELECT &lt; PK &gt;,QQQAPPDefaultValues<\/p>\n<p style=\"text-align: left;\">FROM &lt; company &gt;$&lt; table &gt;$BaseAppGUID (SERIALIZABLE)<\/p>\n<p style=\"text-align: left;\">WHERE NOT EXISTS<\/p>\n<p>(<\/p>\n<p>SELECT 1<\/p>\n<p>FROM &lt; company &gt;$&lt; table &gt;$QQQAppGUID<\/p>\n<p>WHERE<\/p>\n<p>&lt; company &gt;$&lt; table &gt;$QQQAppGUID.&lt; PK &gt; = &lt; company &gt;$&lt; table &gt;$BaseAppGUID.&lt; PK &gt;<\/p>\n<p>)<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: left;\">Where:<\/p>\n<ul style=\"text-align: left;\">\n<li><strong>&lt; company &gt;<\/strong> = Company Name. The process repeats for every company in the database.<\/li>\n<li><strong>&lt; table &gt;<\/strong> = Base table that has been extended.<\/li>\n<li><strong>&lt; PK &gt;<\/strong> = Primary key of the table. This could be more than one column, but for readability, the example shows only one column.<\/li>\n<li><strong>BaseAppGUID<\/strong> = GUID of the Microsoft base app or the app being extended.<\/li>\n<li><strong>QQQAppGUID<\/strong> = GUID of the app being installed.<\/li>\n<\/ul>\n<p style=\"text-align: left;\">In summary, these SQL commands ensure that the data in the extension table aligns with the corresponding data in the base app, and unnecessary records are deleted from the extension table.<\/p>\n<p style=\"text-align: left;\">Records in the extension table are inserted or deleted based on their existence in the base app, as seen above.<\/p>\n<p style=\"text-align: left;\">Please consider the following example of usage in the Sales Header table, to understand the need of the synchronization:<\/p>\n<table class=\" alignleft\" width=\"100%\">\n<tbody>\n<tr>\n<td width=\"39%\"><strong>Assumption<\/strong><\/td>\n<td width=\"13%\"><strong>SQL Sales Header Table Base App<\/strong><\/td>\n<td width=\"15%\"><strong>SQL Sales Header Table Extension<\/strong><\/td>\n<td width=\"32%\"><strong>SQL behavior<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"39%\">1. New clean database where only Base App is installed.<\/td>\n<td width=\"13%\">No rows<\/td>\n<td width=\"15%\">No rows<\/td>\n<td width=\"32%\"><\/td>\n<\/tr>\n<tr>\n<td width=\"39%\">2. Insert Record 1 and Record 2.<\/td>\n<td width=\"13%\"><strong>Record 1<\/strong><\/p>\n<p><strong>Record 2<\/strong><\/td>\n<td width=\"15%\">No rows<\/td>\n<td width=\"32%\"><\/td>\n<\/tr>\n<tr>\n<td width=\"39%\">3. Publish and install QQQApp that extends Sales Header table.<\/td>\n<td width=\"13%\">Record 1<\/p>\n<p>Record 2<\/td>\n<td width=\"15%\"><strong>Record 1<\/strong><\/p>\n<p><strong>Record 2<\/strong><\/td>\n<td width=\"32%\">The system inserts into extension tables to match same rows of the Base App.<\/td>\n<\/tr>\n<tr>\n<td width=\"39%\">4. Insert Record 3.<\/td>\n<td width=\"13%\">Record 1<\/p>\n<p>Record 2<\/p>\n<p><strong>Record 3<\/strong><\/td>\n<td width=\"15%\">Record 1<\/p>\n<p>Record 2<\/p>\n<p><strong>Record 3<\/strong><\/td>\n<td width=\"32%\">The system inserts into extension tables to match same rows of the Base App.<\/td>\n<\/tr>\n<tr>\n<td width=\"39%\">5. Uninstall QQQApp that extend Sales Header.<\/td>\n<td width=\"13%\">Record 1<\/p>\n<p>Record 2<\/p>\n<p>Record 3<\/td>\n<td width=\"15%\">Record 1<\/p>\n<p>Record 2<\/p>\n<p>Record 3<\/td>\n<td width=\"32%\">The system keeps all the records in the tables (base and extension).<\/td>\n<\/tr>\n<tr>\n<td width=\"39%\">6. Delete Record 2.<\/td>\n<td width=\"13%\">Record 1<\/p>\n<p>Record 3<\/td>\n<td width=\"15%\">Record 1<\/p>\n<p><strong>Record 2<\/strong><\/p>\n<p>Record 3<\/td>\n<td width=\"32%\">Since QQQApp isn\u2019t installed. Record 2 isn\u2019t deleted from extension table.<\/td>\n<\/tr>\n<tr>\n<td width=\"39%\">7. Re-install QQQApp that extend Sales Header.<\/td>\n<td width=\"13%\">Record 1<\/p>\n<p>Record 3<\/td>\n<td width=\"15%\">Record 1<\/p>\n<p>Record 3<\/td>\n<td width=\"32%\">Record 2 is deleted from extension table if doesn\u2019t exist in Base App.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Take into account that the more records there are in the base table, the longer the process of synchronizing records between the extension tables and the base table will take.<\/p>\n<p>&nbsp;<\/p>\n<!--themify_builder_content-->\n<div id=\"themify_builder_content-65315\" data-postid=\"65315\" class=\"themify_builder_content themify_builder_content-65315 themify_builder tf_clear\">\n    \t<!-- module_row -->\n\t<div  data-lazy=\"1\" class=\"module_row themify_builder_row tb_nus1581 tb_first tf_clearfix\">\n\t    \t\t<div class=\"row_inner col_align_top col-count-1 tf_box tf_w tf_rel\">\n\t\t\t<div  data-lazy=\"1\" class=\"module_column tb-column col-full first tb_cai8581 tf_box\">\n\t\t\t    \t        <div class=\"tb-column-inner tf_box tf_w\">\n\t\t    <!-- module text -->\n<div  class=\"module module-text tb_9tkr581 arquitps-data  \" data-lazy=\"1\">\n        <div  class=\"tb_text_wrap\">\n    <p><script>\njQuery(\".tbp_post_month:contains(Janeiro)\").html(\"January\");\n\njQuery(\".tbp_post_month:contains(Fevereiro)\").html(\"February\");\n\n\njQuery(\".tbp_post_month:contains(Mar\u00e7o)\").html(\"March\");\n\n\njQuery(\".tbp_post_month:contains(Abril)\").html(\"April\");\n\n\njQuery(\".tbp_post_month:contains(Maio)\").html(\"May\");\n\n\njQuery(\".tbp_post_month:contains(Junho)\").html(\"June\");\n\n\njQuery(\".tbp_post_month:contains(Julho)\").html(\"July\");\n\njQuery(\".tbp_post_month:contains(Agosto)\").html(\"August\");\n\njQuery(\".tbp_post_month:contains(Setembro)\").html(\"September\");\n\njQuery(\".tbp_post_month:contains(Outubro)\").html(\"October\");\n\njQuery(\".tbp_post_month:contains(Novembro)\").html(\"November\");\n\njQuery(\".tbp_post_month:contains(Dezembro)\").html(\"December\");\t\n\n\n\n<\/script><\/p>    <\/div>\n<\/div>\n<!-- \/module text -->\t        <\/div>\n\t    \t<\/div>\n\t\t    <\/div>\n\t    <!-- \/row_inner -->\n\t<\/div>\n\t<!-- \/module_row -->\n\t\t<!-- module_row -->\n\t<div  data-anchor=\"sucesso\" data-hide-anchor=\"1\" data-lazy=\"1\" class=\"module_row themify_builder_row sucesso repeat tb_has_section tb_section-sucesso tb_kaxw827 tf_clearfix\" >\n\t    \t\t<div class=\"row_inner col_align_top col-count-1 tf_box tf_w tf_rel\">\n\t\t\t<div  data-lazy=\"1\" class=\"module_column tb-column col-full first tb_tkvz827 tf_box\">\n\t\t\t    \t        <div class=\"tb-column-inner tf_box tf_w\">\n\t\t    <!-- module buttons -->\n<div  class=\"module module-buttons tb_845w828 buttons-horizontal transparent popmake-24705 large circle tf_textc\" data-lazy=\"1\">\n    \t<div class=\"module-buttons-item tf_inline_b\">\n\t\t\t\t\t\t\t<a href=\"#\" class=\"ui builder_button tb_default_color\" >\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"tf_inline_b tf_vmiddle\">Give as a Feedback and Suggest Questions<\/span>\n\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t    \t<\/div>\n\t<\/div>\n<!-- \/module buttons -->\n\t        <\/div>\n\t    \t<\/div>\n\t\t    <\/div>\n\t    <!-- \/row_inner -->\n\t<\/div>\n\t<!-- \/module_row -->\n\t<\/div>\n<!--\/themify_builder_content-->\n","protected":false},"excerpt":{"rendered":"<p>Every table extension in Business Central corresponds to a different table in SQL database. &nbsp; For example: Customer table in SQL from the Base App Customer extension table in SQL from the other app No. No. Name QQQ Field 1 Address QQQ Field 2 Address 2 Post Code \u2026 When installing an app with table [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":65321,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2099,2124],"tags":[2475,1339,2015,2476],"acf":[],"_links":{"self":[{"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/posts\/65315"}],"collection":[{"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/comments?post=65315"}],"version-history":[{"count":0,"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/posts\/65315\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/media\/65321"}],"wp:attachment":[{"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/media?parent=65315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/categories?post=65315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/arquiconsult.com\/en\/wp-json\/wp\/v2\/tags?post=65315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}