diff --git a/404.html b/404.html index 07bca021a..dfd8eedac 100644 --- a/404.html +++ b/404.html @@ -10,7 +10,7 @@ - +
diff --git a/assets/js/18f12793.8450e097.js b/assets/js/18f12793.8450e097.js deleted file mode 100644 index a7c43210f..000000000 --- a/assets/js/18f12793.8450e097.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmd=self.webpackChunkmd||[]).push([[4799],{4785:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>h});var i=n(5893),o=n(1151),a=n(1872);const s={id:"sfmc-sql-debugging-value-length",title:"SFMC SQL Debugging Value Length",sidebar_label:"Debugging Value Length",description:"Your Automations crash due to longer than expected values coming from the external source? Make your life easier with SQL.",image:"img/og/og-image-sql-debugging-value-length.png",tags:["Marketing Cloud","SQL","Snippet","Data Extensions","Debugging","Automation"]},l=void 0,r={id:"sql/snippets/sfmc-sql-debugging-value-length",title:"SFMC SQL Debugging Value Length",description:"Your Automations crash due to longer than expected values coming from the external source? Make your life easier with SQL.",source:"@site/docs/sql/snippets/sfmc-sql-debugging-value-length.mdx",sourceDirName:"sql/snippets",slug:"/sql/snippets/sfmc-sql-debugging-value-length",permalink:"/docs/sql/snippets/sfmc-sql-debugging-value-length",draft:!1,unlisted:!1,editUrl:"https://github.com/MateuszDabrowski/mateuszdabrowski.pl/edit/master/docs/sql/snippets/sfmc-sql-debugging-value-length.mdx",tags:[{label:"Marketing Cloud",permalink:"/docs/tags/marketing-cloud"},{label:"SQL",permalink:"/docs/tags/sql"},{label:"Snippet",permalink:"/docs/tags/snippet"},{label:"Data Extensions",permalink:"/docs/tags/data-extensions"},{label:"Debugging",permalink:"/docs/tags/debugging"},{label:"Automation",permalink:"/docs/tags/automation"}],version:"current",lastUpdatedBy:"Mateusz D\u0105browski",lastUpdatedAt:1708642896,formattedLastUpdatedAt:"Feb 22, 2024",frontMatter:{id:"sfmc-sql-debugging-value-length",title:"SFMC SQL Debugging Value Length",sidebar_label:"Debugging Value Length",description:"Your Automations crash due to longer than expected values coming from the external source? Make your life easier with SQL.",image:"img/og/og-image-sql-debugging-value-length.png",tags:["Marketing Cloud","SQL","Snippet","Data Extensions","Debugging","Automation"]},sidebar:"snippets",previous:{title:"Debugging Email Sends",permalink:"/docs/sql/snippets/sfmc-sql-debugging-email-sends"},next:{title:"MC Personalization Snippets",permalink:"/docs/category/mc-personalization-snippets"}},c={},h=[{value:"Problem with recommended Data Extension total field length",id:"problem-with-recommended-data-extension-total-field-length",level:2},{value:"Short Term Solution",id:"short-term-solution",level:2},{value:"Discovery with MAX LEN",id:"discovery-with-max-len",level:3},{value:"Debugging with MAX LEN",id:"debugging-with-max-len",level:3},{value:"Basic Long Term Solution",id:"basic-long-term-solution",level:2},{value:"Options",id:"options",level:2},{value:"Show fields with too long value",id:"show-fields-with-too-long-value",level:3},{value:"Extended length information",id:"extended-length-information",level:3},{value:"Fully-fledged Long Term Solution",id:"fully-fledged-long-term-solution",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.m,{content:"Your Automations crash due to longer than expected values coming from the external source? Make your life easier with SQL."}),"\n",(0,i.jsx)(t.h2,{id:"problem-with-recommended-data-extension-total-field-length",children:"Problem with recommended Data Extension total field length"}),"\n",(0,i.jsx)(t.p,{children:"Working with Marketing Cloud (or any other Marketing Automation Platform) is always the dance between optimisation and flexibility. It is easily visible when working with SFMC Data Extensions."}),"\n",(0,i.jsx)(t.p,{children:"On the one hand, limiting the maximum field length is a must-have best practice. Salesforce recommends keeping the total sum of all fields length under 4000 characters. For many use cases, a tiny number. But if you want to have lean Data Extensions to query them quickly, it is the way. And in the Marketing Cloud, nearly everything is a query - even if you don't write a line of SQL."}),"\n",(0,i.jsx)(t.p,{children:"On the other hand, it might be tough to limit your Data Extension so much in real-life scenarios. Especially when you are bringing data from other systems. Example? Salesforce CRM integration through Marketing Cloud Connect. The picklist fields from CRM come to Synchronized Data Extensions as 255 character text fields - even if they have only one-digit values associated with it. Select a few such picklists to be available in Marketing Cloud, and you hit the Data Extension character length limit recommended by Salesforce."}),"\n",(0,i.jsx)(t.p,{children:"What to do with that?"}),"\n",(0,i.jsxs)(t.p,{children:["Limit the maximum length of those picklists in the Marketing Cloud Data Extension you use for campaigns. You are sure that your Gender field will always have one character value (",(0,i.jsx)(t.code,{children:"F"}),"/",(0,i.jsx)(t.code,{children:"M"}),"/",(0,i.jsx)(t.code,{children:"O"}),"/",(0,i.jsx)(t.code,{children:"U"}),")? Make the maximum length equal to 1. It is an excellent way to trim unneeded length, but sometimes, you might be surprised, especially with less obvious picklists, like a job title. Similar issues might also come from standard text fields."]}),"\n",(0,i.jsx)(t.p,{children:"Once you build your standard Data Extension with those optimisations in mind, it is time to pull the data from Synchronized Data Extensions."}),"\n",(0,i.jsx)(t.admonition,{title:"You Should Know",type:"note",children:(0,i.jsx)(t.p,{children:"I'm mentioning the Marketing Cloud Connect Synchronized Data Extensions, but you can also leverage it for FTP-based data uploads. The solution will require additional intermediate Data Extension with generous field lengths in place of Marketing Cloud Connect Synchronized Data Extension. Rest will be the same."})}),"\n",(0,i.jsx)(t.p,{children:"All good, until one of the values, exceed the maximum length you set for its field. The Automation crashes with a cryptic error that tells you nothing and can push you for a long crusade to find the culprit. What now?"}),"\n",(0,i.jsx)(t.h2,{id:"short-term-solution",children:"Short Term Solution"}),"\n",(0,i.jsxs)(t.p,{children:["You can make quick manual check with a simple SQL query. Open your ",(0,i.jsx)(t.a,{href:"/docs/config/sfmc-appexchange-solutions#query-studio",children:"Query Studio"})," and copy-paste the below code:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",metastring:'title="Sample maximum length checking query on Contact object Synchronized Data Extension"',children:"SELECT\n MAX(LEN(c.Id)) AS SubscriberKey\n , MAX(LEN(c.FirstName)) AS FirstName\n , MAX(LEN(c.LastName)) AS LastName\n , MAX(LEN(c.Email)) AS EmailAddress\n , MAX(LEN(c.JobTitle__c)) AS CurrentRole\n , MAX(LEN(c.Industry__c)) AS Industry\nFROM Contact_Salesforce AS c\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"You Should Know",type:"note",children:(0,i.jsxs)(t.p,{children:["If you are running those queries from the child Business Unit, add ",(0,i.jsx)(t.code,{children:"Ent."})," prefix to Synchronized Data Extension names, as those are stored on the parent level."]})}),"\n",(0,i.jsxs)(t.p,{children:["This query will output one row of data with the current maximum length of the values that you have in your Synchronized Data Extension for the selected fields. It uses ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-numeric-functions#min-and-max",children:(0,i.jsx)(t.code,{children:"MAX"})})," function on the ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-string-functions#len",children:(0,i.jsx)(t.code,{children:"LEN"})})," outcome to find the single maximum length available across all records. It has two great uses:"]}),"\n",(0,i.jsx)(t.h3,{id:"discovery-with-max-len",children:"Discovery with MAX LEN"}),"\n",(0,i.jsx)(t.p,{children:"You can use it even before configuring the Data Extension and Profile Attributes to analyse your real-life data."}),"\n",(0,i.jsx)(t.p,{children:"For example, if out of your whole database, the longest First Name is 33 characters, you will probably be just fine with a maximum length of 40 on this field. If a picklist field returns you 5 with this query - you won't need the default 255 characters."}),"\n",(0,i.jsx)(t.p,{children:"Of course, as mentioned above, the values might get longer in the future. But as Marketing Cloud allows you to change maximum field length up but not down, it might be a good idea to try as low as reasonable and leave space for growth."}),"\n",(0,i.jsx)(t.h3,{id:"debugging-with-max-len",children:"Debugging with MAX LEN"}),"\n",(0,i.jsxs)(t.p,{children:["The second use of the above snippet is quick debugging when an error occurs. Execute it in ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-basics#query-studio",children:"Query Studio"})," and compare against the column lengths you set up in your Data Extension. If you see in Query Studio any value longer than the maximum you set up in Data Extension - you found a culprit."]}),"\n",(0,i.jsx)(t.p,{children:"Now you can look in the data source and check whether this longer-than-expected value is correct. If yes, it is time to update your maximum length in the Data Extension and Profile Attribute configuration."}),"\n",(0,i.jsxs)(t.admonition,{title:"You Should Know",type:"note",children:[(0,i.jsx)(t.p,{children:"In most cases, the field length of 255 should be more than enough. But if you need it, Marketing Cloud allows you to go up to 4000 characters per field."}),(0,i.jsxs)(t.p,{children:["4000 characters length is an instant way of getting over the recommended limit, but it might be useful for logging Data Extensions that you won't query in the future. For example, if you want to save ",(0,i.jsxs)(t.a,{href:"/docs/config/sfmc-system-data-views#_bounce",children:[(0,i.jsx)(t.code,{children:"_Bounce"})," Data View"]})," to standard Data Extension, ",(0,i.jsx)(t.code,{children:"SMTPBounceReason"})," might use such a long field."]}),(0,i.jsxs)(t.p,{children:["If you need more, there is a trick reported by ",(0,i.jsx)(t.a,{href:"https://salesforce.stackexchange.com/questions/154402/data-extension-maximum-characters-of-text-field/154403",children:"Markus Slabina"}),". Use Email Studio to add a new field and make the length empty. Save. It will create a ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-conversion-functions#data-types",children:(0,i.jsx)(t.code,{children:"nvarchar(max)"})})," field that allows absurdly long data to be stored."]}),(0,i.jsx)(t.p,{children:"Remember that:"}),(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"It works only in Email Studio - Contact Builder won't work"}),"\n",(0,i.jsx)(t.li,{children:"It is a workaround and might disappear at any moment"}),"\n",(0,i.jsx)(t.li,{children:"You shouldn't use it unless there is no other option"}),"\n"]})]}),"\n",(0,i.jsx)(t.h2,{id:"basic-long-term-solution",children:"Basic Long Term Solution"}),"\n",(0,i.jsx)(t.p,{children:"The snippet above is nice but suitable only for short term manual checks. And you don't want to perform manual checks for the long term. If you wonder whether there is a way to automate it nicely, you are here for a treat."}),"\n",(0,i.jsx)(t.p,{children:"Yes, you can automate such validation by using two additional Activities."}),"\n",(0,i.jsx)(t.p,{children:"Go to the Automation that takes care of moving the data from Synchronized Data Extension do Standard Data Extension and Profile Attributes. Before the Activities that are transfering the data, add a SQL Query Activity. In it, paste the below code:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",metastring:'title="Basic field length checking query"',children:"SELECT\n c.Id AS ContactID\n , LEN(c.Id) AS SubscriberKey\n , LEN(c.FirstName) AS FirstName\n , LEN(c.LastName) AS LastName\n , LEN(c.Email) AS EmailAddress\n , LEN(c.JobTitle__c) AS JobTitle\n , LEN(c.Industry__c) AS Industry\nFROM Contact_Salesforce AS c\nWHERE\n 18 - LEN(c.Id) < 0\n OR 40 - LEN(c.FirstName) < 0\n OR 80 - LEN(c.LastName) < 0\n OR 254 - LEN(c.Email) < 0\n OR 80 - LEN(c.JobTitle__c) < 0\n OR 40 - LEN(c.Industry__c) < 0\n"})}),"\n",(0,i.jsx)(t.p,{children:"Of course, you will want to adapt it to your needs. Change the fields along with their names and lengths. Select the right Synchronized Data Extension. How? Let's dive in what this code does so that you can make it your own."}),"\n",(0,i.jsxs)(t.p,{children:["The first field we ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-select",children:(0,i.jsx)(t.code,{children:"SELECT"})})," is the Unique Identifier (Contact ID / Subscriber Key or other based on the specific object you are validating). It is useful to quickly know which record(s) should you checked when some values lengths exceed the expectations."]}),"\n",(0,i.jsxs)(t.p,{children:["After that, you can see the standard ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-from",children:(0,i.jsx)(t.code,{children:"FROM"})})," statement. You can, of course, ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-join",children:(0,i.jsx)(t.code,{children:"JOIN"})})," additional data sources."]}),"\n",(0,i.jsxs)(t.p,{children:["Finally, there is a ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-where",children:(0,i.jsx)(t.code,{children:"WHERE"})})," statement. In it, we are checking whether at least one field on each record has a value longer than expected. To adapt it - change the number on the left to the length of the field you set up in the target Data Extension / Profile Attribute."]}),"\n",(0,i.jsx)(t.p,{children:"This SQL Query Activity should output the rows to a technical Value Length Data Extension with all the same columns as the target Data Extension / Profile Attributes list. However, it can have much shorter max lengths for the columns, as all fields but the Unique Identifier one will output only the field's length (up to 4 digits). Configure the SQL Activity to Overwrite the technical Data Extension and always have the latest state data."}),"\n",(0,i.jsx)(t.p,{children:"Right after this SQL Query Activity add Verification Activity and configure it to check the technical Data Extension mentioned above. If there is any row in it - it should stop the whole Automation and send an alert email to the Marketing Cloud administrator."}),"\n",(0,i.jsx)(t.p,{children:"To sum up, sample Automation could look like this:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"SQL Query Activity with the Debugging Value Length query"}),"\n",(0,i.jsx)(t.li,{children:"Verification Activity that checks Value Length Data Extension"}),"\n",(0,i.jsx)(t.li,{children:"SQL Query Activity that moves data from Synchronized Data Extension to target Data Extension"}),"\n",(0,i.jsx)(t.li,{children:"Export Activity"}),"\n",(0,i.jsx)(t.li,{children:"Transfer Activity"}),"\n",(0,i.jsx)(t.li,{children:"Import Activity"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The last three Activities above are the classic ETL group for updating the All Subscribers and Profile Attributes."}),"\n",(0,i.jsx)(t.p,{children:"Such setup won't silently crash your Automation whenever there is a single value longer than expected. It will stop the Automation before the crash, inform the administrator that there is an issue and provide Unique Identifiers of records leading to that error for an easy check. Neat, right? Well, it can be even better."}),"\n",(0,i.jsx)(t.h2,{id:"options",children:"Options"}),"\n",(0,i.jsx)(t.p,{children:"The basic version above is already lovely, but we can make a few improvements to make the administrator's life even easier."}),"\n",(0,i.jsx)(t.h3,{id:"show-fields-with-too-long-value",children:"Show fields with too long value"}),"\n",(0,i.jsx)(t.p,{children:"Previously shown query will show the problematic record, but it will display all field lengths for it. The administrator will still have to compare the lengths to find which one is the issue's source."}),"\n",(0,i.jsxs)(t.p,{children:["However, we already are coding the expected field length in the ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-from",children:(0,i.jsx)(t.code,{children:"FROM"})})," part of the query. Why not use it to make life easier?"]}),"\n",(0,i.jsxs)(t.p,{children:["Let's change the ",(0,i.jsx)(t.code,{children:"LEN(c.Id) AS [Subscriber Key],"})," in the ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-select",children:(0,i.jsx)(t.code,{children:"SELECT"})})," statement part to something a bit more interesting:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",metastring:'title="Use CASE to display only the problematic fields"',children:"CASE\n WHEN 18 - LEN(c.Id) < 0\n THEN LEN(c.Id)\nEND AS SubscriberKey\n"})}),"\n",(0,i.jsxs)(t.p,{children:["As you can see, we changed a simple line to a more complex ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-case#conditional-values-with-case",children:(0,i.jsx)(t.code,{children:"CASE"})})," statement. There is a good reason for it. Thanks to it, the query will evaluate each field against the expected length and in the Value Length Data Extension display information only for the problematic values."]}),"\n",(0,i.jsx)(t.p,{children:"The administrator will no longer have to compare each field with configured maximum - he will see it directly in the Data Extension, which saves time and limits the errors."}),"\n",(0,i.jsx)(t.h3,{id:"extended-length-information",children:"Extended length information"}),"\n",(0,i.jsxs)(t.p,{children:["We can go even further with this approach and add a bit more data to the output for those problematic fields by making few calculations in ",(0,i.jsx)(t.code,{children:"THEN"})," part of the ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-case#conditional-values-with-case",children:(0,i.jsx)(t.code,{children:"CASE"})})," statement."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",metastring:'{3} title="Let the code do the work"',children:"CASE\n WHEN 18 - LEN(c.Id) < 0\n THEN CONCAT(LEN(c.Id), '(', LEN(c.Id) - 18, ' over limit)')\nEND AS SubscriberKey\n"})}),"\n",(0,i.jsx)(t.p,{children:"Here, apart from the problematic field's length, we are also showing how much it exceeds the current configuration."}),"\n",(0,i.jsxs)(t.p,{children:["For example, if we expect the First Name to be under 40 characters and one record comes with 46 characters, the previous solution would output ",(0,i.jsx)(t.code,{children:"46"}),". This extended one will be a bit more verbose by showing ",(0,i.jsx)(t.code,{children:"46 (6 over limit)"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"Remember that if you implement this option, it will impact the output length in your technical Data Extension. 4 characters will be no longer enough. 22, however, will work like a charm."}),"\n",(0,i.jsx)(t.h2,{id:"fully-fledged-long-term-solution",children:"Fully-fledged Long Term Solution"}),"\n",(0,i.jsxs)(t.p,{children:["After applying both of the above options to the ",(0,i.jsx)(t.a,{href:"#basic-long-term-solution",children:"Basic SQL Snippet"}),", it looks like this:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",children:"SELECT\n c.Id AS ContactID\n , CASE\n WHEN 18 - LEN(c.Id) < 0\n THEN CONCAT(LEN(c.Id), '(', LEN(c.Id) - 18, ' over limit)')\n END AS SubscriberKey\n , CASE\n WHEN 40 - LEN(c.FirstName) < 0\n THEN CONCAT(LEN(c.FirstName), '(', LEN(c.FirstName) - 40, ' over limit)')\n END AS FirstName\n , CASE\n WHEN 80 - LEN(c.LastName) < 0\n THEN CONCAT(LEN(c.LastName), '(', LEN(c.LastName) - 80, ' over limit)')\n END AS LastName\n , CASE\n WHEN 254 - LEN(c.Email) < 0\n THEN CONCAT(LEN(c.Email), '(', LEN(c.Email) - 254, ' over limit)')\n END AS EmailAddress\n , CASE\n WHEN 80 - LEN(c.JobTitle__c) < 0\n THEN CONCAT(LEN(c.JobTitle__c), '(', LEN(c.JobTitle__c) - 80, ' over limit)')\n END AS JobTitle\n , CASE\n WHEN 40 - LEN(c.Industry__c) < 0\n THEN CONCAT(LEN(c.Industry__c), '(', LEN(c.Industry__c) - 40, ' over limit)')\n END AS Industry\nFROM Contact_Salesforce AS c\nWHERE\n 18 - LEN(c.Id) < 0\n OR 40 - LEN(c.FirstName) < 0\n OR 80 - LEN(c.LastName) < 0\n OR 254 - LEN(c.Email) < 0\n OR 80 - LEN(c.JobTitle__c) < 0\n OR 40 - LEN(c.Industry__c) < 0\n"})})]})}function u(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1872:(e,t,n)=>{n.d(t,{m:()=>a});n(7294);const i="leadText_qzwo";var o=n(5893);const a=e=>{let{content:t}=e;return(0,o.jsx)(o.Fragment,{children:(0,o.jsx)("p",{id:i,children:t})})}},1151:(e,t,n)=>{n.d(t,{Z:()=>l,a:()=>s});var i=n(7294);const o={},a=i.createContext(o);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/18f12793.df77193a.js b/assets/js/18f12793.df77193a.js new file mode 100644 index 000000000..a8153d25b --- /dev/null +++ b/assets/js/18f12793.df77193a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmd=self.webpackChunkmd||[]).push([[4799],{4785:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>h});var i=n(5893),o=n(1151),a=n(1872);const s={id:"sfmc-sql-debugging-value-length",title:"SFMC SQL Debugging Value Length",sidebar_label:"Debugging Value Length",description:"Your Automations crash due to longer than expected values coming from the external source? Make your life easier with SQL.",image:"img/og/og-image-sql-debugging-value-length.png",tags:["Marketing Cloud","SQL","Snippet","Data Extensions","Debugging","Automation"]},l=void 0,r={id:"sql/snippets/sfmc-sql-debugging-value-length",title:"SFMC SQL Debugging Value Length",description:"Your Automations crash due to longer than expected values coming from the external source? Make your life easier with SQL.",source:"@site/docs/sql/snippets/sfmc-sql-debugging-value-length.mdx",sourceDirName:"sql/snippets",slug:"/sql/snippets/sfmc-sql-debugging-value-length",permalink:"/docs/sql/snippets/sfmc-sql-debugging-value-length",draft:!1,unlisted:!1,editUrl:"https://github.com/MateuszDabrowski/mateuszdabrowski.pl/edit/master/docs/sql/snippets/sfmc-sql-debugging-value-length.mdx",tags:[{label:"Marketing Cloud",permalink:"/docs/tags/marketing-cloud"},{label:"SQL",permalink:"/docs/tags/sql"},{label:"Snippet",permalink:"/docs/tags/snippet"},{label:"Data Extensions",permalink:"/docs/tags/data-extensions"},{label:"Debugging",permalink:"/docs/tags/debugging"},{label:"Automation",permalink:"/docs/tags/automation"}],version:"current",lastUpdatedBy:"Mateusz D\u0105browski",lastUpdatedAt:1708643095,formattedLastUpdatedAt:"Feb 22, 2024",frontMatter:{id:"sfmc-sql-debugging-value-length",title:"SFMC SQL Debugging Value Length",sidebar_label:"Debugging Value Length",description:"Your Automations crash due to longer than expected values coming from the external source? Make your life easier with SQL.",image:"img/og/og-image-sql-debugging-value-length.png",tags:["Marketing Cloud","SQL","Snippet","Data Extensions","Debugging","Automation"]},sidebar:"snippets",previous:{title:"Debugging Email Sends",permalink:"/docs/sql/snippets/sfmc-sql-debugging-email-sends"},next:{title:"MC Personalization Snippets",permalink:"/docs/category/mc-personalization-snippets"}},c={},h=[{value:"Problem with recommended Data Extension total field length",id:"problem-with-recommended-data-extension-total-field-length",level:2},{value:"Short Term Solution",id:"short-term-solution",level:2},{value:"Discovery with MAX LEN",id:"discovery-with-max-len",level:3},{value:"Debugging with MAX LEN",id:"debugging-with-max-len",level:3},{value:"Basic Long Term Solution",id:"basic-long-term-solution",level:2},{value:"Options",id:"options",level:2},{value:"Show fields with too long value",id:"show-fields-with-too-long-value",level:3},{value:"Extended length information",id:"extended-length-information",level:3},{value:"Fully-fledged Long Term Solution",id:"fully-fledged-long-term-solution",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.m,{content:"Your Automations crash due to longer than expected values coming from the external source? Make your life easier with SQL."}),"\n",(0,i.jsx)(t.h2,{id:"problem-with-recommended-data-extension-total-field-length",children:"Problem with recommended Data Extension total field length"}),"\n",(0,i.jsx)(t.p,{children:"Working with Marketing Cloud (or any other Marketing Automation Platform) is always the dance between optimisation and flexibility. It is easily visible when working with SFMC Data Extensions."}),"\n",(0,i.jsx)(t.p,{children:"On the one hand, limiting the maximum field length is a must-have best practice. Salesforce recommends keeping the total sum of all fields length under 4000 characters. For many use cases, a tiny number. But if you want to have lean Data Extensions to query them quickly, it is the way. And in the Marketing Cloud, nearly everything is a query - even if you don't write a line of SQL."}),"\n",(0,i.jsx)(t.p,{children:"On the other hand, it might be tough to limit your Data Extension so much in real-life scenarios. Especially when you are bringing data from other systems. Example? Salesforce CRM integration through Marketing Cloud Connect. The picklist fields from CRM come to Synchronized Data Extensions as 255 character text fields - even if they have only one-digit values associated with it. Select a few such picklists to be available in Marketing Cloud, and you hit the Data Extension character length limit recommended by Salesforce."}),"\n",(0,i.jsx)(t.p,{children:"What to do with that?"}),"\n",(0,i.jsxs)(t.p,{children:["Limit the maximum length of those picklists in the Marketing Cloud Data Extension you use for campaigns. You are sure that your Gender field will always have one character value (",(0,i.jsx)(t.code,{children:"F"}),"/",(0,i.jsx)(t.code,{children:"M"}),"/",(0,i.jsx)(t.code,{children:"O"}),"/",(0,i.jsx)(t.code,{children:"U"}),")? Make the maximum length equal to 1. It is an excellent way to trim unneeded length, but sometimes, you might be surprised, especially with less obvious picklists, like a job title. Similar issues might also come from standard text fields."]}),"\n",(0,i.jsx)(t.p,{children:"Once you build your standard Data Extension with those optimisations in mind, it is time to pull the data from Synchronized Data Extensions."}),"\n",(0,i.jsx)(t.admonition,{title:"You Should Know",type:"note",children:(0,i.jsx)(t.p,{children:"I'm mentioning the Marketing Cloud Connect Synchronized Data Extensions, but you can also leverage it for FTP-based data uploads. The solution will require additional intermediate Data Extension with generous field lengths in place of Marketing Cloud Connect Synchronized Data Extension. Rest will be the same."})}),"\n",(0,i.jsx)(t.p,{children:"All good, until one of the values, exceed the maximum length you set for its field. The Automation crashes with a cryptic error that tells you nothing and can push you for a long crusade to find the culprit. What now?"}),"\n",(0,i.jsx)(t.h2,{id:"short-term-solution",children:"Short Term Solution"}),"\n",(0,i.jsxs)(t.p,{children:["You can make quick manual check with a simple SQL query. Open your ",(0,i.jsx)(t.a,{href:"/docs/config/sfmc-appexchange-solutions#query-studio",children:"Query Studio"})," and copy-paste the below code:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",metastring:'title="Sample maximum length checking query on Contact object Synchronized Data Extension"',children:"SELECT\n MAX(LEN(c.Id)) AS SubscriberKey\n , MAX(LEN(c.FirstName)) AS FirstName\n , MAX(LEN(c.LastName)) AS LastName\n , MAX(LEN(c.Email)) AS EmailAddress\n , MAX(LEN(c.JobTitle__c)) AS CurrentRole\n , MAX(LEN(c.Industry__c)) AS Industry\nFROM Contact_Salesforce AS c\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"You Should Know",type:"note",children:(0,i.jsxs)(t.p,{children:["If you are running those queries from the child Business Unit, add ",(0,i.jsx)(t.code,{children:"Ent."})," prefix to Synchronized Data Extension names, as those are stored on the parent level."]})}),"\n",(0,i.jsxs)(t.p,{children:["This query will output one row of data with the current maximum length of the values that you have in your Synchronized Data Extension for the selected fields. It uses ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-numeric-functions#min-and-max",children:(0,i.jsx)(t.code,{children:"MAX"})})," function on the ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-string-functions#len",children:(0,i.jsx)(t.code,{children:"LEN"})})," outcome to find the single maximum length available across all records. It has two great uses:"]}),"\n",(0,i.jsx)(t.h3,{id:"discovery-with-max-len",children:"Discovery with MAX LEN"}),"\n",(0,i.jsx)(t.p,{children:"You can use it even before configuring the Data Extension and Profile Attributes to analyse your real-life data."}),"\n",(0,i.jsx)(t.p,{children:"For example, if out of your whole database, the longest First Name is 33 characters, you will probably be just fine with a maximum length of 40 on this field. If a picklist field returns you 5 with this query - you won't need the default 255 characters."}),"\n",(0,i.jsx)(t.p,{children:"Of course, as mentioned above, the values might get longer in the future. But as Marketing Cloud allows you to change maximum field length up but not down, it might be a good idea to try as low as reasonable and leave space for growth."}),"\n",(0,i.jsx)(t.h3,{id:"debugging-with-max-len",children:"Debugging with MAX LEN"}),"\n",(0,i.jsxs)(t.p,{children:["The second use of the above snippet is quick debugging when an error occurs. Execute it in ",(0,i.jsx)(t.a,{href:"/docs/config/sfmc-appexchange-solutions#query-studio",children:"Query Studio"})," and compare against the column lengths you set up in your Data Extension. If you see in Query Studio any value longer than the maximum you set up in Data Extension - you found a culprit."]}),"\n",(0,i.jsx)(t.p,{children:"Now you can look in the data source and check whether this longer-than-expected value is correct. If yes, it is time to update your maximum length in the Data Extension and Profile Attribute configuration."}),"\n",(0,i.jsxs)(t.admonition,{title:"You Should Know",type:"note",children:[(0,i.jsx)(t.p,{children:"In most cases, the field length of 255 should be more than enough. But if you need it, Marketing Cloud allows you to go up to 4000 characters per field."}),(0,i.jsxs)(t.p,{children:["4000 characters length is an instant way of getting over the recommended limit, but it might be useful for logging Data Extensions that you won't query in the future. For example, if you want to save ",(0,i.jsxs)(t.a,{href:"/docs/config/sfmc-system-data-views#_bounce",children:[(0,i.jsx)(t.code,{children:"_Bounce"})," Data View"]})," to standard Data Extension, ",(0,i.jsx)(t.code,{children:"SMTPBounceReason"})," might use such a long field."]}),(0,i.jsxs)(t.p,{children:["If you need more, there is a trick reported by ",(0,i.jsx)(t.a,{href:"https://salesforce.stackexchange.com/questions/154402/data-extension-maximum-characters-of-text-field/154403",children:"Markus Slabina"}),". Use Email Studio to add a new field and make the length empty. Save. It will create a ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-conversion-functions#data-types",children:(0,i.jsx)(t.code,{children:"nvarchar(max)"})})," field that allows absurdly long data to be stored."]}),(0,i.jsx)(t.p,{children:"Remember that:"}),(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"It works only in Email Studio - Contact Builder won't work"}),"\n",(0,i.jsx)(t.li,{children:"It is a workaround and might disappear at any moment"}),"\n",(0,i.jsx)(t.li,{children:"You shouldn't use it unless there is no other option"}),"\n"]})]}),"\n",(0,i.jsx)(t.h2,{id:"basic-long-term-solution",children:"Basic Long Term Solution"}),"\n",(0,i.jsx)(t.p,{children:"The snippet above is nice but suitable only for short term manual checks. And you don't want to perform manual checks for the long term. If you wonder whether there is a way to automate it nicely, you are here for a treat."}),"\n",(0,i.jsx)(t.p,{children:"Yes, you can automate such validation by using two additional Activities."}),"\n",(0,i.jsx)(t.p,{children:"Go to the Automation that takes care of moving the data from Synchronized Data Extension do Standard Data Extension and Profile Attributes. Before the Activities that are transfering the data, add a SQL Query Activity. In it, paste the below code:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",metastring:'title="Basic field length checking query"',children:"SELECT\n c.Id AS ContactID\n , LEN(c.Id) AS SubscriberKey\n , LEN(c.FirstName) AS FirstName\n , LEN(c.LastName) AS LastName\n , LEN(c.Email) AS EmailAddress\n , LEN(c.JobTitle__c) AS JobTitle\n , LEN(c.Industry__c) AS Industry\nFROM Contact_Salesforce AS c\nWHERE\n 18 - LEN(c.Id) < 0\n OR 40 - LEN(c.FirstName) < 0\n OR 80 - LEN(c.LastName) < 0\n OR 254 - LEN(c.Email) < 0\n OR 80 - LEN(c.JobTitle__c) < 0\n OR 40 - LEN(c.Industry__c) < 0\n"})}),"\n",(0,i.jsx)(t.p,{children:"Of course, you will want to adapt it to your needs. Change the fields along with their names and lengths. Select the right Synchronized Data Extension. How? Let's dive in what this code does so that you can make it your own."}),"\n",(0,i.jsxs)(t.p,{children:["The first field we ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-select",children:(0,i.jsx)(t.code,{children:"SELECT"})})," is the Unique Identifier (Contact ID / Subscriber Key or other based on the specific object you are validating). It is useful to quickly know which record(s) should you checked when some values lengths exceed the expectations."]}),"\n",(0,i.jsxs)(t.p,{children:["After that, you can see the standard ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-from",children:(0,i.jsx)(t.code,{children:"FROM"})})," statement. You can, of course, ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-join",children:(0,i.jsx)(t.code,{children:"JOIN"})})," additional data sources."]}),"\n",(0,i.jsxs)(t.p,{children:["Finally, there is a ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-where",children:(0,i.jsx)(t.code,{children:"WHERE"})})," statement. In it, we are checking whether at least one field on each record has a value longer than expected. To adapt it - change the number on the left to the length of the field you set up in the target Data Extension / Profile Attribute."]}),"\n",(0,i.jsx)(t.p,{children:"This SQL Query Activity should output the rows to a technical Value Length Data Extension with all the same columns as the target Data Extension / Profile Attributes list. However, it can have much shorter max lengths for the columns, as all fields but the Unique Identifier one will output only the field's length (up to 4 digits). Configure the SQL Activity to Overwrite the technical Data Extension and always have the latest state data."}),"\n",(0,i.jsx)(t.p,{children:"Right after this SQL Query Activity add Verification Activity and configure it to check the technical Data Extension mentioned above. If there is any row in it - it should stop the whole Automation and send an alert email to the Marketing Cloud administrator."}),"\n",(0,i.jsx)(t.p,{children:"To sum up, sample Automation could look like this:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"SQL Query Activity with the Debugging Value Length query"}),"\n",(0,i.jsx)(t.li,{children:"Verification Activity that checks Value Length Data Extension"}),"\n",(0,i.jsx)(t.li,{children:"SQL Query Activity that moves data from Synchronized Data Extension to target Data Extension"}),"\n",(0,i.jsx)(t.li,{children:"Export Activity"}),"\n",(0,i.jsx)(t.li,{children:"Transfer Activity"}),"\n",(0,i.jsx)(t.li,{children:"Import Activity"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The last three Activities above are the classic ETL group for updating the All Subscribers and Profile Attributes."}),"\n",(0,i.jsx)(t.p,{children:"Such setup won't silently crash your Automation whenever there is a single value longer than expected. It will stop the Automation before the crash, inform the administrator that there is an issue and provide Unique Identifiers of records leading to that error for an easy check. Neat, right? Well, it can be even better."}),"\n",(0,i.jsx)(t.h2,{id:"options",children:"Options"}),"\n",(0,i.jsx)(t.p,{children:"The basic version above is already lovely, but we can make a few improvements to make the administrator's life even easier."}),"\n",(0,i.jsx)(t.h3,{id:"show-fields-with-too-long-value",children:"Show fields with too long value"}),"\n",(0,i.jsx)(t.p,{children:"Previously shown query will show the problematic record, but it will display all field lengths for it. The administrator will still have to compare the lengths to find which one is the issue's source."}),"\n",(0,i.jsxs)(t.p,{children:["However, we already are coding the expected field length in the ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-from",children:(0,i.jsx)(t.code,{children:"FROM"})})," part of the query. Why not use it to make life easier?"]}),"\n",(0,i.jsxs)(t.p,{children:["Let's change the ",(0,i.jsx)(t.code,{children:"LEN(c.Id) AS [Subscriber Key],"})," in the ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-select",children:(0,i.jsx)(t.code,{children:"SELECT"})})," statement part to something a bit more interesting:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",metastring:'title="Use CASE to display only the problematic fields"',children:"CASE\n WHEN 18 - LEN(c.Id) < 0\n THEN LEN(c.Id)\nEND AS SubscriberKey\n"})}),"\n",(0,i.jsxs)(t.p,{children:["As you can see, we changed a simple line to a more complex ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-case#conditional-values-with-case",children:(0,i.jsx)(t.code,{children:"CASE"})})," statement. There is a good reason for it. Thanks to it, the query will evaluate each field against the expected length and in the Value Length Data Extension display information only for the problematic values."]}),"\n",(0,i.jsx)(t.p,{children:"The administrator will no longer have to compare each field with configured maximum - he will see it directly in the Data Extension, which saves time and limits the errors."}),"\n",(0,i.jsx)(t.h3,{id:"extended-length-information",children:"Extended length information"}),"\n",(0,i.jsxs)(t.p,{children:["We can go even further with this approach and add a bit more data to the output for those problematic fields by making few calculations in ",(0,i.jsx)(t.code,{children:"THEN"})," part of the ",(0,i.jsx)(t.a,{href:"/docs/sql/sfmc-sql-case#conditional-values-with-case",children:(0,i.jsx)(t.code,{children:"CASE"})})," statement."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",metastring:'{3} title="Let the code do the work"',children:"CASE\n WHEN 18 - LEN(c.Id) < 0\n THEN CONCAT(LEN(c.Id), '(', LEN(c.Id) - 18, ' over limit)')\nEND AS SubscriberKey\n"})}),"\n",(0,i.jsx)(t.p,{children:"Here, apart from the problematic field's length, we are also showing how much it exceeds the current configuration."}),"\n",(0,i.jsxs)(t.p,{children:["For example, if we expect the First Name to be under 40 characters and one record comes with 46 characters, the previous solution would output ",(0,i.jsx)(t.code,{children:"46"}),". This extended one will be a bit more verbose by showing ",(0,i.jsx)(t.code,{children:"46 (6 over limit)"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"Remember that if you implement this option, it will impact the output length in your technical Data Extension. 4 characters will be no longer enough. 22, however, will work like a charm."}),"\n",(0,i.jsx)(t.h2,{id:"fully-fledged-long-term-solution",children:"Fully-fledged Long Term Solution"}),"\n",(0,i.jsxs)(t.p,{children:["After applying both of the above options to the ",(0,i.jsx)(t.a,{href:"#basic-long-term-solution",children:"Basic SQL Snippet"}),", it looks like this:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sql",children:"SELECT\n c.Id AS ContactID\n , CASE\n WHEN 18 - LEN(c.Id) < 0\n THEN CONCAT(LEN(c.Id), '(', LEN(c.Id) - 18, ' over limit)')\n END AS SubscriberKey\n , CASE\n WHEN 40 - LEN(c.FirstName) < 0\n THEN CONCAT(LEN(c.FirstName), '(', LEN(c.FirstName) - 40, ' over limit)')\n END AS FirstName\n , CASE\n WHEN 80 - LEN(c.LastName) < 0\n THEN CONCAT(LEN(c.LastName), '(', LEN(c.LastName) - 80, ' over limit)')\n END AS LastName\n , CASE\n WHEN 254 - LEN(c.Email) < 0\n THEN CONCAT(LEN(c.Email), '(', LEN(c.Email) - 254, ' over limit)')\n END AS EmailAddress\n , CASE\n WHEN 80 - LEN(c.JobTitle__c) < 0\n THEN CONCAT(LEN(c.JobTitle__c), '(', LEN(c.JobTitle__c) - 80, ' over limit)')\n END AS JobTitle\n , CASE\n WHEN 40 - LEN(c.Industry__c) < 0\n THEN CONCAT(LEN(c.Industry__c), '(', LEN(c.Industry__c) - 40, ' over limit)')\n END AS Industry\nFROM Contact_Salesforce AS c\nWHERE\n 18 - LEN(c.Id) < 0\n OR 40 - LEN(c.FirstName) < 0\n OR 80 - LEN(c.LastName) < 0\n OR 254 - LEN(c.Email) < 0\n OR 80 - LEN(c.JobTitle__c) < 0\n OR 40 - LEN(c.Industry__c) < 0\n"})})]})}function u(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1872:(e,t,n)=>{n.d(t,{m:()=>a});n(7294);const i="leadText_qzwo";var o=n(5893);const a=e=>{let{content:t}=e;return(0,o.jsx)(o.Fragment,{children:(0,o.jsx)("p",{id:i,children:t})})}},1151:(e,t,n)=>{n.d(t,{Z:()=>l,a:()=>s});var i=n(7294);const o={},a=i.createContext(o);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.2b4f95ba.js b/assets/js/runtime~main.db1aaf8d.js similarity index 99% rename from assets/js/runtime~main.2b4f95ba.js rename to assets/js/runtime~main.db1aaf8d.js index 1dab40d90..6ea39cd0b 100644 --- a/assets/js/runtime~main.2b4f95ba.js +++ b/assets/js/runtime~main.db1aaf8d.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,f,c,d={},b={};function t(e){var a=b[e];if(void 0!==a)return a.exports;var f=b[e]={exports:{}};return d[e].call(f.exports,f,f.exports,t),f.exports}t.m=d,e=[],t.O=(a,f,c,d)=>{if(!f){var b=1/0;for(i=0;iFirstly, you will need to create an id
attribute to mark the container in which you want to display the counter. It might be on the <p>
element for an inline solution or on <div>
element were you to create a more visual version.
Next, the spans. Add empty <span>
elements with the class
corresponding to the time unit you want to show. JavaScript will swap it for the correct numeric value and dynamically change it as time passes. You can add just hours, or you can go for full spectrum.
For example, did you know there is only 148 days, 21 hours, 15 minutes and 26 seconds left till 55th anniversary of the first moon landing?
+For example, did you know there is only 148 days, 21 hours, 12 minutes and 21 seconds left till 55th anniversary of the first moon landing?
<p id="counter1">
For example, did you know there is only <span class="days"></span> days, <span class="hours"></span> hours, <span class="minutes"></span> minutes and <span class="seconds"></span> seconds left till 50th anniversary of the first moonlanding?
</p>
<script>
function getTimeRemaining(endtime) {
const now = new Date().getTime();
const t = endtime - now;
const seconds = Math.floor((t / 1000) % 60);
const minutes = Math.floor((t / 1000 / 60) % 60);
const hours = Math.floor((t / (1000 * 60 * 60)) % 24);
const days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(element, endtime) {
const clock = document.querySelector(element);
const daysSpan = clock.querySelector('.days');
const hoursSpan = clock.querySelector('.hours');
const minutesSpan = clock.querySelector('.minutes');
const secondsSpan = clock.querySelector('.seconds');
function updateClock() {
const t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
const timeinterval = setInterval(updateClock, 1000);
}
/* Declare deadline time */
const deadline = new Date("2019-07-20T20:17:00+00:00").getTime()
/* Trigger counter function by targeting specific element and passing the above deadline */
initializeClock('#counter1', deadline);
</script>
There is much more fun in the JavaScript part. Worry not - you don't need to know the language at all. Let's have a look at the lines to understand what is happening on the general level and then focus on personalisation options.
diff --git a/docs/js/snippets/export-import-document-sfmc-roles/index.html b/docs/js/snippets/export-import-document-sfmc-roles/index.html index 7fe943d09..6a7c4d0d9 100644 --- a/docs/js/snippets/export-import-document-sfmc-roles/index.html +++ b/docs/js/snippets/export-import-document-sfmc-roles/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/js/snippets/tailor-with-data/index.html b/docs/js/snippets/tailor-with-data/index.html index 5965d9c0a..7dafa2528 100644 --- a/docs/js/snippets/tailor-with-data/index.html +++ b/docs/js/snippets/tailor-with-data/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-aggregate-functions/index.html b/docs/sql/sfmc-sql-aggregate-functions/index.html index 970f0d5b9..b55d27ec3 100644 --- a/docs/sql/sfmc-sql-aggregate-functions/index.html +++ b/docs/sql/sfmc-sql-aggregate-functions/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-basics/index.html b/docs/sql/sfmc-sql-basics/index.html index 4b41e465a..abafc6338 100644 --- a/docs/sql/sfmc-sql-basics/index.html +++ b/docs/sql/sfmc-sql-basics/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-case/index.html b/docs/sql/sfmc-sql-case/index.html index bd9ab8666..14e4ec48a 100644 --- a/docs/sql/sfmc-sql-case/index.html +++ b/docs/sql/sfmc-sql-case/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-conversion-functions/index.html b/docs/sql/sfmc-sql-conversion-functions/index.html index 48e73841f..fe609e547 100644 --- a/docs/sql/sfmc-sql-conversion-functions/index.html +++ b/docs/sql/sfmc-sql-conversion-functions/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-date-functions/index.html b/docs/sql/sfmc-sql-date-functions/index.html index 00b445560..cc844631c 100644 --- a/docs/sql/sfmc-sql-date-functions/index.html +++ b/docs/sql/sfmc-sql-date-functions/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-from/index.html b/docs/sql/sfmc-sql-from/index.html index 40f230826..4717d4ae3 100644 --- a/docs/sql/sfmc-sql-from/index.html +++ b/docs/sql/sfmc-sql-from/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-join/index.html b/docs/sql/sfmc-sql-join/index.html index a5ad4e75b..454a510fe 100644 --- a/docs/sql/sfmc-sql-join/index.html +++ b/docs/sql/sfmc-sql-join/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-like/index.html b/docs/sql/sfmc-sql-like/index.html index ebb7fbacd..c73bfbffc 100644 --- a/docs/sql/sfmc-sql-like/index.html +++ b/docs/sql/sfmc-sql-like/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-null-functions/index.html b/docs/sql/sfmc-sql-null-functions/index.html index 9923fe1f5..28afa951b 100644 --- a/docs/sql/sfmc-sql-null-functions/index.html +++ b/docs/sql/sfmc-sql-null-functions/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-numeric-functions/index.html b/docs/sql/sfmc-sql-numeric-functions/index.html index 606f2b825..6c5a86130 100644 --- a/docs/sql/sfmc-sql-numeric-functions/index.html +++ b/docs/sql/sfmc-sql-numeric-functions/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-select/index.html b/docs/sql/sfmc-sql-select/index.html index 9d616a078..138edcc05 100644 --- a/docs/sql/sfmc-sql-select/index.html +++ b/docs/sql/sfmc-sql-select/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-string-functions/index.html b/docs/sql/sfmc-sql-string-functions/index.html index 096feb7c2..65a986599 100644 --- a/docs/sql/sfmc-sql-string-functions/index.html +++ b/docs/sql/sfmc-sql-string-functions/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-style-guide/index.html b/docs/sql/sfmc-sql-style-guide/index.html index bbc75b762..576f2abc1 100644 --- a/docs/sql/sfmc-sql-style-guide/index.html +++ b/docs/sql/sfmc-sql-style-guide/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/sfmc-sql-where/index.html b/docs/sql/sfmc-sql-where/index.html index 63b9c28b8..45b4f4481 100644 --- a/docs/sql/sfmc-sql-where/index.html +++ b/docs/sql/sfmc-sql-where/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/snippets/sfmc-sql-debugging-email-sends/index.html b/docs/sql/snippets/sfmc-sql-debugging-email-sends/index.html index 1c86d23e2..284f30459 100644 --- a/docs/sql/snippets/sfmc-sql-debugging-email-sends/index.html +++ b/docs/sql/snippets/sfmc-sql-debugging-email-sends/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/sql/snippets/sfmc-sql-debugging-value-length/index.html b/docs/sql/snippets/sfmc-sql-debugging-value-length/index.html index 936e51717..1862168c8 100644 --- a/docs/sql/snippets/sfmc-sql-debugging-value-length/index.html +++ b/docs/sql/snippets/sfmc-sql-debugging-value-length/index.html @@ -10,7 +10,7 @@ - + @@ -34,7 +34,7 @@For example, if out of your whole database, the longest First Name is 33 characters, you will probably be just fine with a maximum length of 40 on this field. If a picklist field returns you 5 with this query - you won't need the default 255 characters.
Of course, as mentioned above, the values might get longer in the future. But as Marketing Cloud allows you to change maximum field length up but not down, it might be a good idea to try as low as reasonable and leave space for growth.
The second use of the above snippet is quick debugging when an error occurs. Execute it in Query Studio and compare against the column lengths you set up in your Data Extension. If you see in Query Studio any value longer than the maximum you set up in Data Extension - you found a culprit.
+The second use of the above snippet is quick debugging when an error occurs. Execute it in Query Studio and compare against the column lengths you set up in your Data Extension. If you see in Query Studio any value longer than the maximum you set up in Data Extension - you found a culprit.
Now you can look in the data source and check whether this longer-than-expected value is correct. If yes, it is time to update your maximum length in the Data Extension and Profile Attribute configuration.
In most cases, the field length of 255 should be more than enough. But if you need it, Marketing Cloud allows you to go up to 4000 characters per field.
4000 characters length is an instant way of getting over the recommended limit, but it might be useful for logging Data Extensions that you won't query in the future. For example, if you want to save _Bounce
Data View to standard Data Extension, SMTPBounceReason
might use such a long field.
If you need more, there is a trick reported by Markus Slabina. Use Email Studio to add a new field and make the length empty. Save. It will create a nvarchar(max)
field that allows absurdly long data to be stored.
Remember that:
Remember that if you implement this option, it will impact the output length in your technical Data Extension. 4 characters will be no longer enough. 22, however, will work like a charm.
After applying both of the above options to the Basic SQL Snippet, it looks like this:
-SELECT
c.Id AS ContactID
, CASE
WHEN 18 - LEN(c.Id) < 0
THEN CONCAT(LEN(c.Id), '(', LEN(c.Id) - 18, ' over limit)')
END AS SubscriberKey
, CASE
WHEN 40 - LEN(c.FirstName) < 0
THEN CONCAT(LEN(c.FirstName), '(', LEN(c.FirstName) - 40, ' over limit)')
END AS FirstName
, CASE
WHEN 80 - LEN(c.LastName) < 0
THEN CONCAT(LEN(c.LastName), '(', LEN(c.LastName) - 80, ' over limit)')
END AS LastName
, CASE
WHEN 254 - LEN(c.Email) < 0
THEN CONCAT(LEN(c.Email), '(', LEN(c.Email) - 254, ' over limit)')
END AS EmailAddress
, CASE
WHEN 80 - LEN(c.JobTitle__c) < 0
THEN CONCAT(LEN(c.JobTitle__c), '(', LEN(c.JobTitle__c) - 80, ' over limit)')
END AS JobTitle
, CASE
WHEN 40 - LEN(c.Industry__c) < 0
THEN CONCAT(LEN(c.Industry__c), '(', LEN(c.Industry__c) - 40, ' over limit)')
END AS Industry
FROM Contact_Salesforce AS c
WHERE
18 - LEN(c.Id) < 0
OR 40 - LEN(c.FirstName) < 0
OR 80 - LEN(c.LastName) < 0
OR 254 - LEN(c.Email) < 0
OR 80 - LEN(c.JobTitle__c) < 0
OR 40 - LEN(c.Industry__c) < 0
SELECT
c.Id AS ContactID
, CASE
WHEN 18 - LEN(c.Id) < 0
THEN CONCAT(LEN(c.Id), '(', LEN(c.Id) - 18, ' over limit)')
END AS SubscriberKey
, CASE
WHEN 40 - LEN(c.FirstName) < 0
THEN CONCAT(LEN(c.FirstName), '(', LEN(c.FirstName) - 40, ' over limit)')
END AS FirstName
, CASE
WHEN 80 - LEN(c.LastName) < 0
THEN CONCAT(LEN(c.LastName), '(', LEN(c.LastName) - 80, ' over limit)')
END AS LastName
, CASE
WHEN 254 - LEN(c.Email) < 0
THEN CONCAT(LEN(c.Email), '(', LEN(c.Email) - 254, ' over limit)')
END AS EmailAddress
, CASE
WHEN 80 - LEN(c.JobTitle__c) < 0
THEN CONCAT(LEN(c.JobTitle__c), '(', LEN(c.JobTitle__c) - 80, ' over limit)')
END AS JobTitle
, CASE
WHEN 40 - LEN(c.Industry__c) < 0
THEN CONCAT(LEN(c.Industry__c), '(', LEN(c.Industry__c) - 40, ' over limit)')
END AS Industry
FROM Contact_Salesforce AS c
WHERE
18 - LEN(c.Id) < 0
OR 40 - LEN(c.FirstName) < 0
OR 80 - LEN(c.LastName) < 0
OR 254 - LEN(c.Email) < 0
OR 80 - LEN(c.JobTitle__c) < 0
OR 40 - LEN(c.Industry__c) < 0