字符型字段查询时使用数值输入报1213错误分析
用户反应通过类似于 select * from ttab where col1 = 1001 这样的SQL查询报1213错误,而之前能正常运行。
> select * from ttab where col1 = 1001;
1213: A character to numeric conversion process failed
Error in line 1
Near character position 35
1213错误是 A character to numeric conversion process failed. 即存在字符转换为数值类型出现错误。
检查ttab表,发现col1字段是varchar,但用户表示该字段中都是类似于1001这样的数字编号。我们知道如果字段是char及varchar等字符型时,需要使用引号表示引用的是字符;当没有引号时,会对字段数据进行转换。这种情况下报无法转换,可能表中存在无法转换为数值的记录。
于是对该查询字段col1进行检查,果然发现有"col10999"这样的数据,无法进行转换到数值型,于是出现报错。
> select * from ttab where col1 like "col%";
col1 col10999
col2 col20999
col3 col30999
col4 col40999
1 row(s) retrieved.
另此字段上有索引,但where条件中指明了 col1 = 1001,按理不应该会因col10999这样的值报错,我们检查一下sqexplain的结果来验证一下:
QUERY: (OPTIMIZATION TIMESTAMP: 07-03-2015 13:17:28)
------
select * from ttab where col1 = 1001
Estimated Cost: 43
Estimated # of Rows Returned: 1
1) informix.ttab: INDEX PATH
(1) Index Name: informix.ix_ttab_col1
Index Keys: col1 (Key-First) (Serial, fragments: ALL)
Index Key Filters: (informix.ttab.col1 = 1001 )
Query statistics:
-----------------
Table map :
----------------------------
Internal name Table name
----------------------------
t1 ttab
type table rows_prod est_rows rows_scan time est_cost
-------------------------------------------------------------------
scan t1 1 1 1001 00:00.00 43
QUERY: (OPTIMIZATION TIMESTAMP: 07-03-2015 13:17:39)
------
select * from ttab where col1 = '1001'
Estimated Cost: 1
Estimated # of Rows Returned: 1
1) informix.ttab: INDEX PATH
(1) Index Name: informix.ix_ttab_col1
Index Keys: col1 (Serial, fragments: ALL)
Lower Index Filter: informix.ttab.col1 = '1001'
Query statistics:
-----------------
Table map :
----------------------------
Internal name Table name
----------------------------
t1 ttab
type table rows_prod est_rows rows_scan time est_cost
-------------------------------------------------------------------
scan t1 1 1 1 00:00.00 1
我们发现,如果没有使用引号时,输入是数值,虽然使用了索引,但扫描了整个索引,并将每个记录数值转换与输入值进行匹配,如果碰到了无法转换的数据,将报错;而使用了引号时,输入是字符型,在索引中直接就定位到了相应的记录。
结论:当执行SQL查询时,应尽可能的根据字段类型来确定输入值类型,以减少不必要的麻烦。