字符型字段查询时使用数值输入报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查询时,应尽可能的根据字段类型来确定输入值类型,以减少不必要的麻烦。

标签: none

添加新评论