zoukankan      html  css  js  c++  java
  • 不要让SQLServer自动转换害了你!

          SQLServer有很强的格式自动转换功能,但是他不是万能的,有些时候也是转换不了的,而且出现错误我们很难查找,因为我们有些时候是可以的,有些时候又出现问题。正确之时都是SQLServer格式转换范围内的,那些超出界限的,就会出现错误,而出现错误的时候,我们的程序员就会陷入一个误区:检查别的地方代码,而且为此浪费很多的时间,贻误了工程进度,对项目来说是有害的,对自己来说,更是有害的。下面有个例子,我们可以参考一下,借此说明此问题。

    问题陈述:
    有一天,执行
    SELECT * FROM XXX_ORIGINAL_20031205
    where msgid=62010388000012

    语句,结果SQL Server报告出错:“将数据类型 varchar 转换为 numeric 时出错。”

    这是什么意思呢?

    Msgid这个字段的类型是:varchar(30)。

    原因分析:
    不是SQL Server突然不能从数字自动转换为字符串,而是单单对这个字段的数值有问题,这也和这个字段中实际已存储的字符串有关。

    你看,我执行这个SQL语句是没有问题,可以自动转换:

    SELECT * FROM XXXX_ORIGINAL_20031205
    where recordid=62010388000012

    recordid这个字段的类型也是:varchar(30)。
    这为什么就可以呢?

    为什么?

    这是因为msgid字段的真实数值是类似于这样的字符串“12051113280101053509”,由于你的SQL命令中要求拿字符串跟我们提供的这个数字62010388000012匹配,所以SQLServer默认要把这么多个“12051113280101053509”先统统转换为数字,再去跟62010388000012匹配。

    (首先这就涉及到一个效率问题,转换这么多msgid成为数字,再跟你的数字匹配,将是一个多么大的浪费啊)

    当然,这回SQLServer转不过来了,因为“12051113280101053509”换为数字实在太大了,超出了范围,所以你看SQLServer于是乎报告“将数据类型 varchar 转换为 numeric 时出错”,他指的就是把历史数据“12051113280101053509”这个varchar(30)转成numeric不行,而不是把你SQL脚本传递的参数62010388000012转换失败。

    让我们看看另一种形式的错误,就更清楚了:

    我们执行

    SELECT * FROM XXXX_ORIGINAL_20031205
    where msgid=120

    命令就会得到错误:

    varchar 值 '12050003010101026986' 的转换溢出了 int 列。超出了最大整数值。

    这个错误,是不是很清楚地表明了SQLServer在帮你执行SQL命令时背后所作的事情?

    他试图帮你主动把记录中的这个字段转换成你在SQL命令中指明的那个数据类型。

    总结:

    很多时候,我们懒得去看某个字段到底是什么类型,是char,还是tinyint,还是bool,还是varchar,我们就随便写一个数字,让聪明的SQL Server自己去判断该转成什么。

    再次我将聪明的SQL Server自动转换给我们带来的害处简单罗列:

    1、增加出错次数,而且出现错误容易让我们陷入误区,让我们的程序不够健壮。
    2、自动转换会增加SQL的执行时间,让我们的程序没有效率。
    3、给我们程序带来无限隐患,为后期的功能延伸带来麻烦


    建议:

    不积硅步何以至千里,千里长堤溃于蚁穴。希望程序员兄弟们以次为鉴,自己勤快一点,养成一个好的习惯,在错误产生之前搞定他。请自己判断好格式,然后将数据传给SQLServer,因为相信机器,不如相信自己。

  • 相关阅读:
    《需求工程——软件建模与分析》读后感之三
    项目目标文档
    利益相关者描述案例
    《需求工程——软件建模与分析》读后感之二
    《需求工程——软件建模与分析》读后感之一
    专业实训题目需求分析
    《代码之美》读后感
    计算“1”的数量
    团队冲刺第九天
    linux df 命令
  • 原文地址:https://www.cnblogs.com/skylaugh/p/664031.html
Copyright © 2011-2022 走看看