<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eduardo Ortega</title>
    <description>The latest articles on DEV Community by Eduardo Ortega (@eduardo-ortega).</description>
    <link>https://dev.to/eduardo-ortega</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4074936%2F5da18a27-8b43-47ae-bdc0-9c16c53d931a.jpg</url>
      <title>DEV Community: Eduardo Ortega</title>
      <link>https://dev.to/eduardo-ortega</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eduardo-ortega"/>
    <language>en</language>
    <item>
      <title>The SQL Worked Perfectly. The Data Was Wrong.</title>
      <dc:creator>Eduardo Ortega</dc:creator>
      <pubDate>Wed, 12 Aug 2026 14:46:50 +0000</pubDate>
      <link>https://dev.to/eduardo-ortega/the-sql-worked-perfectly-the-data-was-wrong-44de</link>
      <guid>https://dev.to/eduardo-ortega/the-sql-worked-perfectly-the-data-was-wrong-44de</guid>
      <description>&lt;p&gt;&lt;em&gt;A 30-minute database update turned into half a morning trying to explain something that shouldn't have been possible.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It was supposed to take 30 minutes.&lt;/p&gt;

&lt;p&gt;A user needed some data corrected before they could generate a report. They sent us an Excel file with the records that needed to be updated.&lt;/p&gt;

&lt;p&gt;Nothing unusual.&lt;/p&gt;

&lt;p&gt;I needed to turn those rows into SQL &lt;code&gt;UPDATE&lt;/code&gt; statements.&lt;/p&gt;

&lt;p&gt;So I did what many developers have probably done at some point: I built an Excel formula, dragged it down, copied the generated SQL into a file, checked a few statements, and sent it to Production.&lt;/p&gt;

&lt;p&gt;The generated SQL looked completely normal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Pending'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10482&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Approved'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10483&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Review'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10484&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Pending'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10485&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Approved'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10486&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- ... many more&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Valid SQL. Valid IDs. Valid statuses. Valid dates.&lt;/p&gt;

&lt;p&gt;Nothing jumped out.&lt;/p&gt;

&lt;p&gt;Production executed it. No errors. SQL Server was happy.&lt;/p&gt;

&lt;p&gt;We told the user the data was ready.&lt;/p&gt;

&lt;p&gt;A few minutes later, a message came back:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The data is wrong.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  But the script worked
&lt;/h2&gt;

&lt;p&gt;We checked the obvious things.&lt;/p&gt;

&lt;p&gt;The script had executed. The records existed. The rows had been updated. There were no SQL errors.&lt;/p&gt;

&lt;p&gt;The values in the database matched the values in the script.&lt;/p&gt;

&lt;p&gt;Maybe something had gone wrong during execution.&lt;/p&gt;

&lt;p&gt;So the script was executed again. This time we made absolutely sure it completed.&lt;/p&gt;

&lt;p&gt;It did.&lt;/p&gt;

&lt;p&gt;No errors.&lt;/p&gt;

&lt;p&gt;We told the user to try again.&lt;/p&gt;

&lt;p&gt;The response came back:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;It's still wrong. I can't generate my report with this data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's when the 30-minute task stopped being a 30-minute task.&lt;/p&gt;

&lt;p&gt;Now Development was looking at it. Production was involved. The user was waiting.&lt;/p&gt;

&lt;p&gt;And we had one of those problems where every technical check tells you everything is working.&lt;/p&gt;

&lt;p&gt;The database matched the script. The script had executed successfully.&lt;/p&gt;

&lt;p&gt;Yet the result was wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  We were comparing the wrong things
&lt;/h2&gt;

&lt;p&gt;Eventually, someone suggested something simple:&lt;/p&gt;

&lt;p&gt;Stop comparing the database with the SQL script.&lt;/p&gt;

&lt;p&gt;Compare the SQL script with the &lt;strong&gt;original Excel file&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So we did.&lt;/p&gt;

&lt;p&gt;And that's when things started getting uncomfortable.&lt;/p&gt;

&lt;p&gt;Imagine part of the source looked like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CustomerId&lt;/th&gt;
&lt;th&gt;Requested Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10482&lt;/td&gt;
&lt;td&gt;Pending&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10483&lt;/td&gt;
&lt;td&gt;Pending&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10484&lt;/td&gt;
&lt;td&gt;Approved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10485&lt;/td&gt;
&lt;td&gt;Review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10486&lt;/td&gt;
&lt;td&gt;Approved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10487&lt;/td&gt;
&lt;td&gt;Approved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10488&lt;/td&gt;
&lt;td&gt;Rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now compare that with the generated SQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Review'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10482&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Approved'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10483&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Rejected'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10484&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Pending'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10485&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;Customers&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Approved'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2026-08-10'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10486&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There was no obvious sequence.&lt;/p&gt;

&lt;p&gt;Some values even matched by coincidence. But others clearly didn't.&lt;/p&gt;

&lt;p&gt;We started comparing records one by one.&lt;/p&gt;

&lt;p&gt;The IDs were right. The dates were right.&lt;/p&gt;

&lt;p&gt;But the statuses weren't coming from the same rows.&lt;/p&gt;

&lt;p&gt;At that point, the database was no longer our main suspect.&lt;/p&gt;

&lt;p&gt;Something had happened &lt;strong&gt;before the SQL was generated&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So I went back to the Excel formula.&lt;/p&gt;

&lt;p&gt;And there it was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;="UPDATE Customers SET Status='"&amp;amp;B22&amp;amp;"', UpdateDate='"&amp;amp;C2&amp;amp;"' WHERE CustomerId="&amp;amp;A2&amp;amp;";"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look carefully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CustomerId  → A2
Status      → B22
UpdateDate  → C2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;B22.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not &lt;code&gt;B2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;B22&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One extra character.&lt;/p&gt;

&lt;p&gt;The customer ID came from the current row. The date came from the current row.&lt;/p&gt;

&lt;p&gt;The status came from &lt;strong&gt;twenty rows below it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And then I had dragged that formula down.&lt;/p&gt;

&lt;p&gt;Excel had done exactly what I told it to do.&lt;/p&gt;

&lt;p&gt;SQL Server had done exactly what I told it to do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Twice.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For about two seconds, finding the problem felt like relief.&lt;/p&gt;

&lt;p&gt;Then someone asked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Okay. How much data did this script touch?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the relief disappeared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding the bug didn't fix the data
&lt;/h2&gt;

&lt;p&gt;The incorrect values were already in Production.&lt;/p&gt;

&lt;p&gt;Knowing that &lt;code&gt;B22&lt;/code&gt; should have been &lt;code&gt;B2&lt;/code&gt; didn't magically restore them.&lt;/p&gt;

&lt;p&gt;Now we needed another script.&lt;/p&gt;

&lt;p&gt;And after what had just happened, nobody was particularly excited to hear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't worry. I'll generate another one.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We went back to the original source and generated the correction.&lt;/p&gt;

&lt;p&gt;This time, we compared the source data against the generated SQL much more carefully. We validated samples.&lt;/p&gt;

&lt;p&gt;Production executed the corrective script.&lt;/p&gt;

&lt;p&gt;We checked again.&lt;/p&gt;

&lt;p&gt;Then the user checked.&lt;/p&gt;

&lt;p&gt;Finally, the message came back:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;It's correct now. I can generate the report.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What should have been a routine 30-minute request had consumed a good part of the morning.&lt;/p&gt;

&lt;p&gt;The user could finally continue. The data was fixed.&lt;/p&gt;

&lt;p&gt;I thought the incident was over.&lt;/p&gt;

&lt;p&gt;It wasn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then my manager called me
&lt;/h2&gt;

&lt;p&gt;He wasn't interested in whether &lt;code&gt;B22&lt;/code&gt; should have been &lt;code&gt;B2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We already knew that.&lt;/p&gt;

&lt;p&gt;He asked a much more uncomfortable question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How are we going to prevent this from happening again?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The easiest answer would have been:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I'll be more careful next time.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But that's not risk mitigation.&lt;/p&gt;

&lt;p&gt;That's hope.&lt;/p&gt;

&lt;p&gt;Developers make mistakes.&lt;/p&gt;

&lt;p&gt;The real problem was that &lt;strong&gt;one wrong cell reference could generate an entire set of perfectly valid SQL statements and make it all the way to Production.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Excel didn't know the relationship was wrong.&lt;/p&gt;

&lt;p&gt;The SQL parser didn't know.&lt;/p&gt;

&lt;p&gt;The database didn't know.&lt;/p&gt;

&lt;p&gt;Every statement was valid.&lt;/p&gt;

&lt;p&gt;The database simply did exactly what we asked it to do.&lt;/p&gt;

&lt;p&gt;And that was the lesson that stayed with me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SQL didn't fail. That was the problem.
&lt;/h2&gt;

&lt;p&gt;If the formula had produced malformed SQL, this incident would probably have ended much sooner.&lt;/p&gt;

&lt;p&gt;SQL Server would have rejected it. We would have fixed the syntax.&lt;/p&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;p&gt;But this was worse.&lt;/p&gt;

&lt;p&gt;It was valid SQL.&lt;/p&gt;

&lt;p&gt;Using valid values.&lt;/p&gt;

&lt;p&gt;Against valid records.&lt;/p&gt;

&lt;p&gt;With the wrong relationships between them.&lt;/p&gt;

&lt;p&gt;There was nothing for the database engine to complain about.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem wasn't Excel
&lt;/h2&gt;

&lt;p&gt;I still use Excel.&lt;/p&gt;

&lt;p&gt;And yes, you absolutely &lt;em&gt;can&lt;/em&gt; generate SQL with Excel formulas. That's exactly what I was doing.&lt;/p&gt;

&lt;p&gt;The problem was the workflow.&lt;/p&gt;

&lt;p&gt;I already had structured data sitting in rows and columns, but I was manually rebuilding the relationship between those values using references like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A2
B2
C2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One extra character was enough to break that relationship while still producing perfectly executable SQL.&lt;/p&gt;

&lt;p&gt;Eventually, that experience became one of the reasons I built &lt;strong&gt;TableToSQL&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I wanted to import an Excel or CSV file, select the columns that should be updated, select the fields that belong in the &lt;code&gt;WHERE&lt;/code&gt;, and generate the statements directly from each row.&lt;/p&gt;

&lt;p&gt;No SQL concatenation formulas.&lt;/p&gt;

&lt;p&gt;No dragging formulas through thousands of cells.&lt;/p&gt;

&lt;p&gt;No &lt;code&gt;A2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No &lt;code&gt;B2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And definitely no accidental &lt;code&gt;B22&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you ever generate SQL from Excel formulas, I built &lt;a href="https://tabletosql.com" rel="noopener noreferrer"&gt;&lt;strong&gt;TableToSQL&lt;/strong&gt;&lt;/a&gt; for exactly this kind of job.&lt;/p&gt;

&lt;p&gt;And even if you don't, there's still one thing from that morning worth remembering.&lt;/p&gt;

&lt;p&gt;The next time you run a generated script and your database tells you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Commands completed successfully.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't let that message make you too comfortable.&lt;/p&gt;

&lt;p&gt;Because sometimes the SQL failing isn't the scary part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sometimes the scary part is when it works.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>debugging</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
