[转帖]浅析SQL数据类型的隐式转换与显式转换以及隐式转换可能导致的问题
https://www.cnblogs.com/goloving/p/15222604.html
一、隐式类型转换问题
1、隐式类型转换:
比如:SELECT 1 + '1';
2、隐式类型转换的问题:
(1)程序可读性差,且依赖数据库的隐式转换规则,效率差,会增加处理时间;且如果数据库升级,则程序可能无法正确执行;
(2)有可能会导致索引失效;
(3)有可能会导致意想不到的结果;
3、显式类型转换:SELECT 1 + CAST('1' AS SIGNED INT);
4、原则:尽量用显式类型转换。
5、隐式转换问题示例:
(1)数值型 + 字符型
SELECT 1+'1'; -- 结果:2
SELECT CONCAT('北京',2008); -- 结果:北京2008
SELECT '北京' + 2008; -- 结果: 可能2008,可能报错
SELECT 'HELLO ' + 'WORLD!'; -- 结果:可能 0,可能报错
(2)隐式类型转换导致索引失效

CREATE TABLE teacher(
teacher_id VARCHAR(50),
teacher_name VARCHAR(50),
id_no VARCHAR(50)
); CREATE INDEX idx_teacher_id ON teacher(teacher_id); CREATE TABLE student(
student_id INT,
student_name VARCHAR(50),
teacher_id INT
); CREATE INDEX idx_teacher_id ON student(teacher_id); SELECT
*
FROM student a
INNER JOIN teacher b
ON a.teacher_id = b.teacher_id; -- 此时不会走索引,因为在teacher表中,teacher_id是varchar类型,而student表中teacher_id是int类型,
-- 会做隐式类型转换,把varchar转为int类型;

(3)隐式类型转换导致意想不到的结果
SELECT 10/4; -- 结果:2 解决:可以把分母分子乘以1.00,再运算 SELECT COUNT(*) FROM table1; -- count返回的是int类型,如果表中数据量超过count出来的数,就报错
-- 解决:在count(*) 外面cast转换一下,转换为能保存结果的类型

SELECT COUNT(*) FROM teacher WHERE teacher_name = 0;
-- 为什么不是等价于:
SELECT COUNT(*) FROM teacher WHERE teacher_name= '0'; -- 因为隐式类型转换时,转的是左边而不是右边; -- 以下语句会返回两条信息,而不是一条,因为530102192005080114这串数字,已经超过了int类型的范围,
-- 超过了int类型的范围就会转为float类型,等号两边都转为float类型,会丢精度,也就是最后一位数丢了,剩下的就相等了,就全返回了; SELECT COUNT(*) FROM teacher WHERE id_no = 530102192005080114;
-- 等价于:
SELECT COUNT(*) FROM teacher WHERE
CAST(id_no AS DECIMAL) = CAST(530102192005080114 AS DECIMAL); -- 在查询时把530102192005080114加上单引号就可以了;

二、SQL 数据类型转换
数据类型转换分为隐式转换和显式转换。
1、显式转换:顾名思义就是使用函数进行数据类型转化,如cast、convert
2、隐式转换问题

-- 例子1
SELECT 1+ ‘1’ –返回值为2 -- 例子 2
SELECT
CASE
WHEN 1 > 1 THEN 10
WHEN 1 = 1 THEN ‘10’
WHEN 1 < 1 THEN 10.2
END -- 返回值为10.2 -- 例子3
SELECT
CASE
WHEN 1 > 1 THEN 10
WHEN 1 = 1 THEN ‘abc’
WHEN 1 < 1 THEN 10.2
END -- 语法错误

在第一个例子中,'1' 被转换为 int 的 1 ;
在第二个例子中,不管那个后面的条件成立,结果都被转换为decima;
第三个例子由于‘ab’转换为decimal失败,所以报错。
为什么呢? —— 这是因为 sql server 中有多个数据类型在一个表达式中时会存在隐式的转换,各个数据类型的优先级如下:

1、用户定义数据类型(最高)
2、sql_variant
3、xml
4、datetime
5、smalldatetime
6、float
7、real
8、decimal
9、money
10、smallmoney
11、bigint
12、int
13、smallint
14、tinyint
15、bit
16、ntext
17、text
18、image
19、timestamp
20、uniqueidentifier
21、nvarchar(包括 nvarchar(max))
22、nchar
23、varchar (包括 varchar(max))
24、char
25、varbinary(包括 varbinary(max))
26、binary(最低)

当两个不同数据类型的表达式用运算符组合后,数据类型优先级规则指定将优先级较低的数据类型转换为优先级较高的数据类型。 如果此转换不是所支持的隐式转换,则返回错误。 当两个操作数表达式具有相同的数据类型时,运算的结果便为该数据类型。
这里有一篇文章也说了这个 case when 里的隐式转换导致的问题,可以看下:《SQL Server有意思的数据类型隐式转换问题》
[转帖]浅析SQL数据类型的隐式转换与显式转换以及隐式转换可能导致的问题的更多相关文章
- SQL反模式学习笔记19 使用*号,隐式的列
目标:减少输入 反模式:捷径会让你迷失方向 使用通配符和未命名的列能够达到减少输入的目的,但是这个习惯会带来一些危害. 1.破坏代码重构:增加一列后,使用隐式的Insert插入语句报错: 2.查询中使 ...
- VB.Net隐式转换和显式转换的方法(转)
VB.Net隐式转换和显式转换的方法(转) “隐式转换”不需要源代码中的任何特殊语法.在下面的示例中,在将 k 的值赋给 q 之前,Visual Basic 将该值隐式转换成单精度浮点值. Dim ...
- C#中的类型转换-自定义隐式转换和显式转换
目录 前言 基础知识 示例代码 实际应用 问题 答案 报错 用户定义的转换必须是转换成封闭类型,或者从封闭类型转换 参考 其他 应用和设计 读音 参考 前言 有时我们会遇到这么一种情况:在json数据 ...
- SQL数据类型解释
SQL数据类型解释 1.char.varchar.text.ntext.bigint.int.smallint.tinyint和bit的区别及数据库的数据类型电脑秘籍 2009-05-15 21:47 ...
- SQLServer学习笔记<>sql的范围内查找,sql数据类型,字符串处理函数
sql的范围内查找 (1)between.....and用法 通常情况下我们查找一个在某固定区域内的所有记录,可以采用>=,<=来写sql语句,例如:查找订单价格在1000到2000之间的 ...
- java数据类型,hibernate数据类型,标准sql数据类型之间的对应表
Hibernate API简介 其接口分为以下几类: l 提供访问数据库的操作的接口: l 用于配置Hibernate的接口: l 回调接口 l ...
- Java数据类型与SQL数据类型的映射
Java数据类型与SQL数据类型的映射 SQL Data Type Java Data Type char/varchar/longvarchar String numeric/decimal jav ...
- 【转帖】oracle数据类型和对应的java类型
原文地址:http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/java.102/B19275-03/datacc.ht ...
- SQL数据类型(SQL Server六个类型使用)
SQL数据类型是一个属性,它指定任何对象的数据的类型.在SQL中每一列,变量和表达有相关数据类型. 当创建表时,需要使用这些数据类型. 会选择根据表列要求选择一个特定的数据类型. SQL Server ...
- Java,Hibernate,标准sql数据类型之间的对应表
(2010-07-14 19:53:50) 转载▼ 标签: 杂谈 分类: JAVA Hibernate API简介 其接口分为以下几类: l 提供访问数据库的操作的接口: l ...
随机推荐
- 2.elasticsearch中的mapping
mapping 顾名思义,代表了映射关系.是文档中字段和数据类型的映射关系 为什么要了解mapping 虽然elasticsearch中已尽有的动态mapping(Dynamic Mapping),而 ...
- uni-app+vue3+ts项目搭建完整流程
项目代码同步更新至码云 uni-vue3-ts-template 开发前准备 利用 uni-app 开发,有两种方法: 通过 HBuilderX 创建(需安装 HBuilderX 编辑器) 通过命令行 ...
- Skywalking(8.7)安装以及docker镜像打包
Skywalking安装以及docker镜像打包 Skywalking版本:apache-skywalking-apm-es7-8.7.0 ES版本:7.17.2 一.下载Skywalking的安装包 ...
- 神经网络入门篇:直观理解反向传播(Backpropagation intuition)
详细推导反向传播 下图是逻辑回归的推导: 回想一下逻辑回归的公式(参考公式1.2.公式1.5.公式1.6.公式1.15) 公式1.38: \[\left. \begin{array}{l} {x }\ ...
- 云小课|使用SQL加密函数实现数据列的加解密
摘要:数据加密作为有效防止未授权访问和防护数据泄露的技术,在各种信息系统中广泛使用.作为信息系统的核心,GaussDB(DWS)数仓也提供数据加密功能,包括透明加密和使用SQL函数加密. 本文分享自华 ...
- LiteOS内核源码分析:静态内存Static Memory
摘要:本文带领大家一起剖析了LiteOS静态内存模块的源代码,包含静态内存的结构体.静态内存池初始化.静态内存申请.释放.清除内容等. 内存管理模块管理系统的内存资源,它是操作系统的核心模块之一,主要 ...
- Axure 母版与元件
需要重复使用的元件,建议创建成母版: 如果修改了母版,所有页面中的母版元件将会被同步修改 元件:添加后,所有的 Axure 都可以使用 母版:只适用当前的 Axure 原型 拖放行为: 任意位置:可以 ...
- Java 模拟数据库连接池的实现
前面学习过等待 - 通知机制,现在我们在其基础上添加一个超时机制,模拟从连接池中获取.使用和释放连接的过程.客户端获取连接的过程被设定为等待超时模式,即如果在 1000 毫秒内无法获取到可用连接,将会 ...
- 【奥运会】yahoo的这个骚操作令人费解。。。
昨天在朋友圈发了一张截图,貌似很多朋友没有 get 到点,我也实在搞不懂 Yahoo 的这波操作. 默认排序是按照金牌总数,那必然是美国第一名了.不过习惯上不应该是按照金牌总数进行排名吗?毕竟金银铜牌 ...
- COOIS增强
一.订单抬头增强 二.结构添加字段 添加ZGCWL字段 三.BADI增强 四.其他界面增强 不同的界面,选择不同的修改结构 抬头 ct_ioheader 组件 ct_ioopcomp 工序 ct_io ...