{"id":223,"date":"2011-04-10T21:45:13","date_gmt":"2011-04-10T20:45:13","guid":{"rendered":"https:\/\/greladesign.co\/blog\/?p=223"},"modified":"2011-06-30T09:44:58","modified_gmt":"2011-06-30T08:44:58","slug":"sqlite-compare-null-values","status":"publish","type":"post","link":"https:\/\/greladesign.co\/blog\/2011\/04\/10\/sqlite-compare-null-values\/","title":{"rendered":"SQLite &#8211; compare null values"},"content":{"rendered":"<p>Hi,<\/p>\n<p>this is a quick post describing issue I have found when using SQLite in flash. I&#8217;ve tried to fetch some rows using following snippet, but couldn&#8217;t get correct results. Then after digging on the net I have found that there is a different syntax to compare null values. The problem was in comparing values that sometimes can be <em>null<\/em>. <\/p>\n<p>The idea was to get how many empty values I have in the database, the result was always 0. I have start with plain text query (no parameters), but it didn&#8217;t worked as I&#8217;ve found on the SQLite page you can&#8217;t just use equal to compare <em>NULL<\/em> values, you have special syntax IS NULL or IS NOT NULL.<\/p>\n<p><!--more--><br \/>\nFirst sample data:<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n-- Create a test table with data\r\ncreate table t1(a int, b varchar(8), c int);\r\ninsert into t1 values(1,0,0);\r\ninsert into t1 values(2,0,1);\r\ninsert into t1 values(3,1,0);\r\ninsert into t1 values(4,1,1);\r\ninsert into t1 values(5,null,0);\r\ninsert into t1 values(6,null,1);\r\ninsert into t1 values(7,null,null);\r\n<\/pre>\n<p>test snippet (simplified).<\/p>\n<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\nvar statement:SQLStatement = new SQLStatement();\r\nstatement.sqlConnection = m_oConnection;\r\nstatement.text = &quot;SELECT * FROM t1 WHERE b=NULL&quot;;\r\n<\/pre>\n<p>so this will not work, to actually have it working and return null or not null values in column b, you have to use proper syntax for comparing <em>NULL<\/em> values, revised query:<\/p>\n<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\nvar statement:SQLStatement = new SQLStatement();\r\nstatement.sqlConnection = m_oConnection;\r\nstatement.text = &quot;SELECT * FROM t1 WHERE b IS NULL&quot;;\/\/or statement.text = &quot;SELECT * FROM t1 WHERE b IS NOT NULL&quot;;\r\n<\/pre>\n<p>now it will return what was expected, but this doesn&#8217;t solve the problem, because you may found that your query doesn&#8217;t return expected values, this will happen in queries where <em>parameters<\/em> object is used to pass values to the query. <\/p>\n<p>The example above was much simplified, normally you will use the <em>parameters<\/em> object of the SQLStatement instance, as follows.<\/p>\n<p>This will not return expected row (real life example of problem with comparing null values).<\/p>\n<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\nvar compare_a:int= 6;\r\nvar compare_b:String = null;\r\nvar compare_c:int= 1;\r\n\/\/expected 1 row in result\r\nvar statement:SQLStatement = new SQLStatement();\r\nstatement.sqlConnection = m_oConnection;\r\nstatement.text = &quot;SELECT * FROM t1 WHERE a = ? AND b = ? AND c = ?&quot;;\r\nstatement.parameters[0] = compare_a;\r\nstatement.parameters[1] = compare_b;\r\nstatement.parameters[2] = compare_c;\r\n<\/pre>\n<p>as you can see we have a query that accepts any parameter values, including null and because just comparing null value requires different syntax you may find this query to return unexpected results (if any) when either of parameters will be null.<\/p>\n<p>The solution or workaround is to not to allow in database design for null values but some defaults instead i.e. &#8220;Not set&#8221; etc. and use this values in the query, sometimes it is not possible to change database schema, but always you can change the query:)<\/p>\n<p>you can improve above simple example by adding logic branching and checking for null parameter:<\/p>\n<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\nvar compare_a:int= 6;\r\nvar compare_b:String = null;\r\nvar compare_c:int= 1;\r\n\/\/expected 1 row in result\r\nvar statement:SQLStatement = new SQLStatement();\r\nstatement.sqlConnection = m_oConnection;\r\n\r\nif (compare_b != null)\r\n{\r\n\tstatement.text = &quot;SELECT * FROM t1 WHERE a = ? AND b = ? AND c = ?&quot;;\r\n\r\n\tstatement.parameters[0] = compare_a;\r\n\tstatement.parameters[1] = compare_b;\r\n\tstatement.parameters[2] = compare_c;\r\n}\r\nelse\r\n{\r\n\tstatement.text = &quot;SELECT * FROM t1 WHERE a = ? AND b IS NULL AND c = ?&quot;\r\n\r\n\tstatement.parameters[0] = compare_a;\r\n\tstatement.parameters[1] = compare_c;\r\n}\r\n<\/pre>\n<p>It works but only for this simple case, it will be much harder for variable number of parameters where some or all can have null values. To actually make it useful one needs to built some classes that will support dynamically created SQLStatements for which this behaviour will be done automatically, i.e.<\/p>\n<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\nvar query:SelectQuery = new SelectQuery();\r\n\/\/\r\nquery.addFilter(&quot;a&quot;,6);\r\nquery.addFilter(&quot;b&quot;,null);\r\nquery.addFilter(&quot;c&quot;,1);\r\n\/\/\r\n<\/pre>\n<p>and in the hypothetical SelectQuery class:<\/p>\n<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\n\/**\r\n * Returns string for filtering the query (WHERE clause).\r\n *\/\r\nprotected function getFilters():String\r\n{\r\n\tvar _sWhere:String = &quot;&quot;;\r\n\tif (m_aFilters.length == 0) return _sWhere;\r\n\t_sWhere = &quot; WHERE &quot;;\r\n\t\/\/m_aFilters is an array of \r\n       \/\/Objects {column_name, compare_value}\r\n\tfor (var i:int = 0; i &lt; m_aFilters.length; i++)\r\n\t{\r\n\t\tvar filter:Object = m_aFilters[i];\r\n\t\t_sWhere += filter.column_name;\r\n\t\t\r\n\t\tif (filter.compare_value == null)\r\n\t\t{\r\n\t\t\t_sWhere += &quot; IS NULL &quot;;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\t_sWhere += &quot; = ? &quot;;\r\n                        \/\/? will be used in parameters \r\n                        \/\/object;\r\n\t\t}\r\n\t\tif(i &lt; m_aFilters.length-1) _sWhere += &quot; AND &quot;;\r\n                            \/\/for simplicity \r\n                            \/\/it will always group with AND\r\n\t}\r\n\treturn _sWhere;\r\n}\r\n\/\/calling this method with previous snippets data (addFilter), \r\n\/\/produces: WHERE a = ?  AND b IS NULL  AND c = ? \r\n<\/pre>\n<p>Happy coding:)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi, this is a quick post describing issue I have found when using SQLite in flash. I&#8217;ve tried to fetch some rows using following snippet, but couldn&#8217;t get correct results. Then after digging on the net I have found that &hellip; <a href=\"https:\/\/greladesign.co\/blog\/2011\/04\/10\/sqlite-compare-null-values\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":""},"categories":[17,47,9,58],"tags":[302,12,39,50,301,105,55,51,54,88,86],"_links":{"self":[{"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/posts\/223"}],"collection":[{"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/comments?post=223"}],"version-history":[{"count":18,"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/posts\/223\/revisions"}],"predecessor-version":[{"id":377,"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/posts\/223\/revisions\/377"}],"wp:attachment":[{"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/media?parent=223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/categories?post=223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/greladesign.co\/blog\/wp-json\/wp\/v2\/tags?post=223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}