<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Enforcer.net &#187; SQL</title>
	<atom:link href="http://theEnforcer.net/category/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://theEnforcer.net</link>
	<description>a force.com blog</description>
	<lastBuildDate>Thu, 19 Aug 2010 23:03:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Forcing DataLoader to extract numbers when using databaseWrite</title>
		<link>http://theEnforcer.net/2010/06/forcing-dataloader-to-extract-numbers-when-using-databasewrite/</link>
		<comments>http://theEnforcer.net/2010/06/forcing-dataloader-to-extract-numbers-when-using-databasewrite/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 07:34:34 +0000</pubDate>
		<dc:creator>The Enforcer</dc:creator>
				<category><![CDATA[Data Loader]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://theEnforcer.net/?p=237</guid>
		<description><![CDATA[Oh boy, I love debugging! And today I really had to debug DataLoader! I do a lot of stuff with DataLoader — see my previous blogs on the topic. But I&#8217;ve always uploaded to Salesforce from a PostgreSQL database — never extracted. DataLoader allows a job to be configured where a SOQL query is run, [...]]]></description>
			<content:encoded><![CDATA[<p>Oh boy, I love debugging!</p>
<p>And today I really had to debug DataLoader!</p>
<p>I do a lot of stuff with DataLoader — see my <a href="http://theenforcer.net/category/data-loader/">previous blogs on the topic</a>. But I&#8217;ve always uploaded <em>to</em> Salesforce from a PostgreSQL database — never <em>extracted</em>.</p>
<p>DataLoader allows a job to be configured where a SOQL query is run, the data is extracted from Salesforce and the results are inserted into a database. The documentation is woeful on this whole topic, but fortunately DataLoader comes with sample <code>process-conf.xml</code> and <code>database-conf.xml</code> files that contain some examples.</p>
<p>The basic method is:</p>
<ul>
<li><code>process-conf.xml</code> defines the job and includes the SOQL in a <code>extractionSOQL</code> parameter</li>
<li>An <code>SDL</code> file defines the field mapping between Salesforce and the output</li>
<li><code>database-conf.xml</code> defines the SQL statement to use, plus the parameter types</li>
</ul>
<p><strong>First hint:</strong> The Field names in the <code>SDL</code> file are case-sensitive. Use &#8220;ID&#8221; instead of &#8220;Id&#8221; and the field won&#8217;t come across.</p>
<p><strong>Second hint:</strong> All fields come across in quotes. This totally destroys any attempt to load numbers!</p>
<p>Here&#8217;s part of the database-conf.xml that I used:</p>
<pre class="brush: plain;">
&lt;bean id=&quot;extractMegaphoneQuery&quot;
      class=&quot;com.salesforce.dataloader.dao.database.SqlConfig&quot; singleton=&quot;true&quot;&gt;
    &lt;property name=&quot;sqlString&quot;&gt;
        &lt;value&gt;
            INSERT INTO renewals_megaphone (
               period, megaphone_date, opportunity_name, reason_lost, owner, expiry_date, product, years_owned)
            VALUES (@period@, @megaphone_date@, @opportunity_name@, @reason_lost@, @owner@,
                    @expiry_date@, @product@, @years_owned@)
        &lt;/value&gt;
    &lt;/property&gt;
    &lt;property name=&quot;sqlParams&quot;&gt;
        &lt;map&gt;
            &lt;entry key=&quot;period&quot;           value=&quot;bigint&quot;/&gt;
            &lt;entry key=&quot;megaphone_date&quot;   value=&quot;java.sql.Date&quot;/&gt;
            &lt;entry key=&quot;opportunity_name&quot; value=&quot;java.lang.String&quot;/&gt;
            &lt;entry key=&quot;reason_lost&quot;      value=&quot;java.lang.String&quot;/&gt;
            &lt;entry key=&quot;owner&quot;            value=&quot;java.lang.String&quot;/&gt;
            &lt;entry key=&quot;expiry_date&quot;      value=&quot;java.sql.Date&quot;/&gt;
            &lt;entry key=&quot;product&quot;          value=&quot;java.lang.String&quot;/&gt;
            &lt;entry key=&quot;years_owned&quot;      value=&quot;integer&quot;/&gt;
        &lt;/map&gt;
    &lt;/property&gt;
&lt;/bean&gt;
</pre>
<p>You&#8217;ll notice I have two fields that are numbers — <code>period</code> (bigint) and <code>years_owned</code> (integer). When trying to load these fields into my database, I kept getting the message:</p>
<p><code>Sql error: ERROR: column "period" is of type bigint but expression is of type character varying.<br />
org.postgresql.util.PSQLException: ERROR: <span style="color: #ff0000;">column "period" is of type bigint but expression is of type character varying</span></code></p>
<p>There was no way that I could convince DataLoader that the field was numeric — I tried lots of <code>java.lang.Integer</code> type entries in the <code>sqlParams</code>, but didn&#8217;t help.</p>
<p>I then changed the output to <code>csvWrite</code> instead of <code>databaseWrite</code> so that I could see the output, and it came through like this:</p>
<p><code>"PERIOD","MEGAPHONE_DATE","OPPORTUNITY_NAME","REASON_LOST","OWNER","EXPIRY_DATE","PRODUCT","YEARS_OWNED"<br />
"<span style="color: #ff0000;">83823.0</span>","2010-06-08","Joe Smith","Invalid","John","2010-03-14","a0624004000qRtkgA2","<span style="color: #ff0000;">3.0</span>"</code></p>
<p>You&#8217;ll notice that the first and last columns are meant to be numbers, but they are coming through in quotation marks. That&#8217;s what was causing the database load to fail!</p>
<p>So, I updated my SQL to convert the strings to numbers:</p>
<pre class="brush: plain;">
    &lt;property name=&quot;sqlString&quot;&gt;
        &lt;value&gt;
            INSERT INTO renewals_megaphone (
               period, megaphone_date, opportunity_name, reason_lost, owner, expiry_date, product, years_owned)
            VALUES (@period@::numeric, @megaphone_date@, @opportunity_name@, @reason_lost@, @owner@, @expiry_date@, @product@, @years_owned@::numeric)
        &lt;/value&gt;
    &lt;/property&gt;
</pre>
<p>This successfully cast the strings into numbers and they finally got stored in the database (which automatically ignored the decimal places when converting to <code>bigint</code> and <code>integer</code>).</p>
<p>I hope the blog post saves other people similar problems!</p>
<h3>The Bottom Line</h3>
<ul class="nomargin">
<li>DataLoader can extract data and insert it into a database</li>
<li>Numbers are quoted on export and cause database errors</li>
<li>I type-cast the <code>string</code> into <code>numeric</code> to enable the database to load it</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://theEnforcer.net/2010/06/forcing-dataloader-to-extract-numbers-when-using-databasewrite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A UNION made in hell</title>
		<link>http://theEnforcer.net/2008/05/a-union-made-in-hell/</link>
		<comments>http://theEnforcer.net/2008/05/a-union-made-in-hell/#comments</comments>
		<pubDate>Thu, 15 May 2008 11:57:17 +0000</pubDate>
		<dc:creator>The Enforcer</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://theenforcer.net/?p=16</guid>
		<description><![CDATA[Okay, this post isn&#8217;t quite about Salesforce.com today, but I think it&#8217;s a tidbit worth publishing&#8230; I learned something about SQL today! I love SQL — It&#8217;s the only programming language that I learnt back in my University days that is still useful. (Remember Pascal? Ha!) I especially love PostgreSQL. I did some neat procedural [...]]]></description>
			<content:encoded><![CDATA[<p><em>Okay, this post isn&#8217;t quite about Salesforce.com today, but I think it&#8217;s a tidbit worth publishing&#8230;</em></p>
<p><strong>I learned something about SQL today!</strong></p>
<p>I love SQL — It&#8217;s the only programming language that I learnt back in my University days that is still useful. (Remember Pascal? <em>Ha!</em>) I especially love <a title="The world's most advanced open source database" href="http://www.postgresql.org/" target="_blank"><strong>PostgreSQL</strong></a>. I did some <a href="http://blogs.atlassian.com/developer/2007/11/optimizing_postgresql_plpgsql.html">neat procedural stuff</a> with it earlier this year that was especially pleasing.</p>
<p>Anyway, today we were burdened with an overly complex query doing funky stuff with sales data. We were trying to join together two sets of data using the good old <code>UNION</code> statement. Result set A had 20 rows and result set B had 24 rows. When combined with <code>UNION</code>, the result had&#8230; not 44 rows, but 24 rows! This was a real head-scratcher until I found this in the PostgreSQL manual:</p>
<blockquote><p><img style="float:right" src="http://chart.apis.google.com/chart?cht=v&amp;chd=t:20,24,0,4,0,0,0&amp;chs=130x80&amp;chf=bg,s,F3F3EC" alt="" /><code>UNION</code> effectively appends the result of <code><em>query2</em></code> to the result of <code><em>query1</em></code> (although there is no guarantee that this is the order in which the rows are actually returned). Furthermore, it eliminates duplicate rows from its result, in the same way as <code>DISTINCT</code>, unless <code>UNION ALL</code> is used.</p></blockquote>
<p>The kicker is that last sentence — duplicate rows are removed unless <code>UNION ALL</code> is used. Sure enough, we stuck in that <code>ALL</code> word and everything was fine.</p>
<h3>The Bottom Line</h3>
<ul class="nomargin">
<li>You learn something every year</li>
<li>PostgreSQL rocks!</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://theEnforcer.net/2008/05/a-union-made-in-hell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
