<?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>Wangling &#187; SQLite</title>
	<atom:link href="http://wangling.me/tag/sqlite/feed/" rel="self" type="application/rss+xml" />
	<link>http://wangling.me</link>
	<description>I&#039;m Wang Ling. I&#039;m wangling you.</description>
	<lastBuildDate>Sat, 28 Jan 2012 13:48:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>What&#8217;s good about selectionArgs in SQLite queries</title>
		<link>http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/</link>
		<comments>http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 07:29:52 +0000</pubDate>
		<dc:creator>an0</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://blog.wangling.me/?p=149</guid>
		<description><![CDATA[The Android API for querying SQLite databases supports two styles of queries: query&#40;uri, projection, selection = &#34;column=&#34; + value, selectionArgs = null, sortOrder&#41; query&#40;uri, projection, selection = &#34;column=?&#34;, selectionArgs = &#123; value_as_string &#125;, sortOrder&#41; Obviously, the first one is more straightforward and convenient. Then what&#8217;s good about the second one? Let me try to sell [...]]]></description>
			<content:encoded><![CDATA[<p>The Android API for querying SQLite databases supports two styles of queries:</p>
<ol>
<li><span class="code">query<span style="color: #009900;">&#40;</span>uri, projection, selection <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;column=&quot;</span> <span style="color: #339933;">+</span> value, selectionArgs <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span>, sortOrder<span style="color: #009900;">&#41;</span></span></li>
<li><span class="code">query<span style="color: #009900;">&#40;</span>uri, projection, selection <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;column=?&quot;</span>, selectionArgs <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> value_as_string <span style="color: #009900;">&#125;</span>, sortOrder<span style="color: #009900;">&#41;</span></span></li>
</ol>
<p>Obviously, the first one is more straightforward and convenient. Then what&#8217;s good about the second one?</p>
<p>Let me try to sell the goodness of <code>selectionArgs</code> via a simple example.</p>
<p>Suppose you are querying contacts with phone number, say, &#8220;+8612345678901&#8243;. With the first style, you get the WHERE clause <span class="code"><span style="color: #0000ff;">&quot;number=+8612345678901&quot;</span></span> which is the result of string concatenation &#8216;<span class="code"><span style="color: #0000ff;">&quot;number=&quot;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;+8612345678901&quot;</span></span>&#8216;.</p>
<p>It is easy to see that <em>phone numbers</em> are not <em>pure numbers</em>, i.e., they are not <em>numeric</em>. For example, the number &#8220;(010) 87654321 &#8221; and &#8220;010-87654321-001&#8243;, are valid phone numbers, but are neither valid <em>integer</em> nor <em>real</em> numbers<sup><a href="http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/#footnote_0_149" id="identifier_0_149" class="footnote-link footnote-identifier-link" title="Of course, you don&amp;#8217;t want to do the subtraction of the latter.">1</a></sup>. Thus, the the type of the number column (storage class in SQLite&#8217;s idiom) is TEXT.</p>
<p>From this nonnumeric phone number string raises a problem, a quite subtle one. With its <a href="http://www.sqlite.org/datatype3.html">dynamic type system、column affinity and type conversion</a>, SQLite will try to convert &#8220;+8612345678901&#8243; to a text string. But the express &#8220;+8612345678901&#8243; is numeric originally, because it has no quote marks surrounding it, and numeric values are operated according numeric rules first. So it is first normalized to &#8220;8612345678901&#8243;, and then the normalized value is converted to a text string &#8220;<strong>&#8216;</strong>8612345678901<strong>&#8216;</strong>&#8220;. </p>
<p>So the query that is really fed into the SQLite engine is something like this:<br />

<div class="my_codebox"><table><tr><td class="code"><div class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> contacts_table <span style="color: #993333; font-weight: bold;">WHERE</span> number<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'8612345678901'</span></div></td></tr></table></div></p>
<p>But as a text string, &#8217;8612345678901&#8242; can not be matched with &#8216;+8612345678901&#8242;, and the query fails.</p>
<p>We were suffering this kind of adversity until <code>selectionArgs</code> came to save the day.</p>
<p>With the second style, Android SQL query builder will replace <strong>?</strong>s in <code>selection</code> with the values from <code>selectionArgs</code>, in order that they appear in the selection. The values must be <span class="code"><span style="color: #003399;">String</span></span> and will be treated as text strings by SQLite, i.e., they must be converted to their <span class="code"><span style="color: #003399;">String</span></span> representation first if they are not <span class="code"><span style="color: #003399;">String</span></span>, and will be quoted automatically when replacing the <strong>?</strong>s. So the query that is fed into the SQLite engine is something like this:<br />

<div class="my_codebox"><table><tr><td class="code"><div class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> contacts_table <span style="color: #993333; font-weight: bold;">WHERE</span> number<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'+8612345678901'</span></div></td></tr></table></div></p>
<p>At this point, it doesn&#8217;t matter whether the underlying column type is really TEXT or not, because whatever the TEXT value is derived from, it can be correctly cast back to the original column type. The key point is that TEXT can be losslessly converted to any other types, but not necessarily vice versa as shown above.</p>
<p>In fact, we can stick to the first style by manually simulating the works done by Android SQL query builder this way:<br />

<div class="my_codebox"><table><tr><td class="code"><div class="java" style="font-family:monospace;">query<span style="color: #009900;">&#40;</span>uri, projection, selection <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;column=&quot;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;'&quot;</span> <span style="color: #339933;">+</span> value <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;'&quot;</span>, selectionArgs <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span>, sortOrder<span style="color: #009900;">&#41;</span></div></td></tr></table></div></p>
<p>But as you can see, it is such a tedious concatenation with just one query column, you don&#8217;t want to imagine the mess with more complex queries, do you?</p>
<div class="footnotes"><ol ><li id="footnote_0_149" class="footnote">Of course, you don&#8217;t want to do the subtraction of the latter.</li></ol></div><div class="social">			<a href="https://twitter.com/share?url=http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhats-good-about-selectionargs-in-sqlite-queries%2F" class="twitter-share-button" data-url="http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhats-good-about-selectionargs-in-sqlite-queries%2F" data-text="What&#8217;s good about selectionArgs in SQLite queries" data-via="an0" data-count="none">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>			<script type="text/javascript" charset="utf-8">
(function(){
  var _w = 86 , _h = 18;
  var param = {
    url:"http%3A%2F%2Fwangling.me%2F2009%2F08%2Fwhats-good-about-selectionargs-in-sqlite-queries%2F",
    type:'6',
    count:'', /**是否显示分享数，1显示(可选)*/
    appkey:'', /**您申请的应用appkey,显示分享来源(可选)*/
    title:'What&#8217;s good about selectionArgs in SQLite queries', /**分享的文字内容(可选，默认为所在页面的title)*/
    pic:'', /**分享图片的路径(可选)*/
    ralateUid:'1676354212', /**关联用户的UID，分享微博会@该用户(可选)*/
    rnd:new Date().valueOf()
  }
  var temp = [];
  for( var p in param ){
    temp.push(p + '=' + encodeURIComponent( param[p] || '' ) )
  }
  document.write('<iframe allowTransparency="true" frameborder="0" scrolling="no" src="http://hits.sinajs.cn/A1/weiboshare.html?' + temp.join('&') + '" width="'+ _w+'" height="'+_h+'" style="margin-left:5px;"></iframe>')
})()
</script></div>]]></content:encoded>
			<wfw:commentRss>http://wangling.me/2009/08/whats-good-about-selectionargs-in-sqlite-queries/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

