SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: 原文:SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理SQL Server 字段类型 decimal(18,6)小数点前是几位? 不可否认,这是一个很低级的问题.... 为什么会问这么低级的问题? 由于这个问题,导致一个数据导入的SP执行失败....以至于困扰了我好几个小时....   事情是这样的... 公司总部上了一套Oracle的ERP,我们系统中有些数据要从里面取,比如Supplier,Product等。
原文: SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理

SQL Server 字段类型 decimal(18,6)小数点前是几位?

不可否认,这是一个很低级的问题....

为什么会问这么低级的问题?

由于这个问题,导致一个数据导入的SP执行失败....以至于困扰了我好几个小时....

 

事情是这样的...

公司总部上了一套Oracle的ERP,我们系统中有些数据要从里面取,比如Supplier,Product等。

Oracle会导出数据文件,我们同SSIS刷到本地相应的数据库(数据库的字段和Oracle的一致)。

对我们来说就是数据源变了,需要把Oracle的数据转化成我们先系统可以用的数据。

由于Oracle上线比较"快",为了让现有的系统基本能跑起来,同事写一个SP转化导入到我们系统的数据库。

这个SP 写的比较粗糙。

同事只是把Oracle的数据在进行处理之后 AS成现系统的字段。

sql语句是这样的:

SELECT
[DT_UAMT],[DT_DAMT],[DT_AMT]
INTO Temp_DT_PODT
FROM 
(
   NULL AS DT_UAMT
,convert(varchar,convert(decimal(18,6),isnull(usd_amount,'0') * 100)) as DT_DAMT
,convert(varchar,convert(decimal(18,6),isnull(LINE_AMOUNT,'0') * 100)) as DT_AMT
FROM  OracleDB.[dbo].OracleTB 
)

 

当然了 字段不止这三个,一个表有将近100个字段,这里只是举例说明问题。

同事这里用到了SELECT INTO语句。

SQL SELECT INTO 语句可用于创建表的备份复件。

这样写可以快速达到效果不用一个一个表去建并且保证数据可以完全导出过来。

但是这样写会有问题,

1、首先SELECT INTO需要into的这个表不存在,所以每次都需要把Temp_DT_PODT给Drop掉。

2、由于Oracle的字段类型和我们的不一样,会导致创建出来的字段类型和我们原数据库的类型不一样。

3、当用 null as成一个字段的时候,into的表中对应字段类型为int

上述第三条会导致有些之前SP会报错....

你可能会说不用NULL as DT_UAMT用 '' as DT_UAMT。当然是可以的。

我也说过 这个SP是为了之前的系统能够跑起来写的,有些问题存在是正常的.....

 

然后解决这些问题就交给了我.....(我好苦逼,哭晕在厕所....)

毕竟SELECT INTO 语句可用于创建表的备份复件的,我们刷数据还是用insert into的好。

insert into 是需要表的。一个表将近100个字段...一共10几个表.....手动建肯定不可能了

我是这样想的。

之前SP中into的表只是字段数据类型不对,名称都是对的。我只需要把原来的表的字段类型修改对了就行了。

恩,忽然感觉工作量小了很多有没有,哈哈。

我通过数据库 任务->执行脚本  把原SP into的表的结构导出来。

再把原系统用的表结构导出来。

对比两个文件把相应的字段类型改一下。

并记录下修改的字段,写出相应的SQL 语句进行修改。

我在测试数据库中 建了一个测试数据库test

把SP into的表通过导出文件建好。

让执行我整理的SQL 语句。

哈哈,我的工作是不是做完了?

明显没有....在我修改原来的SP 将select into 改成insert into 并执行的时候.....

竟然报错了....

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

我靠,这是什么情况?

我改了很多decimal的...难道我一个一个去试试....

我还真一个一个去试了试。结果发现时DT_DAMT这个字段出错了。

难道是数据问题?数据中有不是数字的数据?

 

select DT_DAMT from  OracleDB.[dbo].OracleTB  where isnumeric(DT_DAMT )!=1

结果返回为空....

我去,都是数字啊。

这是什么情况?

难道长度超出了?

应该不会啊,我建的表中DT_DAMT字段是 decimal(18,6)类型。

并且同事写的SP中也是转化成了 decimal(18,6)

convert(varchar,convert(decimal(18,6),isnull(usd_amount,'0') * 100)) as DT_DAMT

(额。。。貌似还乘以了100.当时没注意到)

 

我看了一下原SP into表的DT_DAMT类型decimal(18,2)

 我靠 decimal(18,2)可以,我的decimal(18,6)就不行?

不过也没影响吧,都是decimal(18,*)的类型,小数点前面应该都是18位。

我之前真的是这么以为的。

于是我在执行了一下sql语句。

Select convert(decimal(18,2),isnull(LINE_AMOUNT,'0') ) as DT_DAMT
FROM OracleDB.[dbo].OracleTB 

没报错....

Select convert(decimal(18,6),isnull(LINE_AMOUNT,'0') ) as DT_DAMT
FROM OracleDB.[dbo].OracleTB 

竟然报错了

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

于是我果断百度一下 Decimal 

 

 

Decimal 数据类型 介绍

 

Decimal为SQL Server、MySql等数据库的一种数据类型,不属于浮点数类型,可以在定义时划定整数部份以及小数部分的位数。使用精确小数类型不仅能够保证数据计算更为精确,还可以节省储存空间,例如百分比使用decimal(4,2)即可。存储数据范围是:-10^38~10^38-1 的固定精度和小数位的数字。一个decimal类型的数据占用了2~17个字节。
decimal[ (p[ , s] )]
p (有效位数)
可储存的最大十进位数总数,小数点左右两侧都包括在内。有效位数必须是 1 至最大有效位数 38 之间的值。预设有效位数是 18。
s (小数位数)
小数点右侧所能储存的最大十进位数。小数位数必须是从 0 到 p 的值。只有在指定了有效位数时,才能指定小数位数。预设小数位数是 0;因此,0 <= s <= p。最大储存体大小会随著有效位数而不同。
Decimal(p,s)表示数值中共有n位数,其中整数p-s位,小数s位。例:decimal(10,6),数值中共有10位数,其中整数占4位,小数占6位。
decimal(10,6),数值中共有10位数,其中整数占4位,小数占6位。

ISNUMERIC 介绍

语法

ISNUMERIC ( expression )

参数  expression  要计算的表达式。

返回类型  int

注释

当输入表达式得数为一个有效的整数、浮点数、moneydecimal 类型,那么 ISNUMERIC 返回 1;否则返回 0。返回值为 1 确保可以将 expression 转换为上述数字类型中的一种。

 

因此记录一下, 以便以后犯同样的错误。
 
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
3天前
|
SQL Oracle 关系型数据库
sql语句创建数据库
在创建数据库之前,请确保你有足够的权限,并且已经考虑了数据库的安全性和性能需求。此外,不同的DBMS可能有特定的最佳实践和配置要求,因此建议查阅相关DBMS的官方文档以获取更详细和准确的信息。
|
15天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
52 10
|
15天前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
88 6
|
2天前
|
SQL 数据管理 关系型数据库
如何在 Windows 上安装 SQL Server,保姆级教程来了!
在Windows上安装SQL Server的详细步骤包括:从官方下载安装程序(如Developer版),选择自定义安装,指定安装位置(非C盘),接受许可条款,选中Microsoft更新,忽略警告,取消“适用于SQL Server的Azure”选项,仅勾选必要功能(不包括Analysis Services)并更改实例目录至非C盘,选择默认实例和Windows身份验证模式,添加当前用户,最后点击安装并等待完成。安装成功后关闭窗口。后续文章将介绍SSMS的安装。
5 0
|
2天前
|
SQL Java 数据库连接
Java从入门到精通:2.3.2数据库编程——了解SQL语言,编写基本查询语句
Java从入门到精通:2.3.2数据库编程——了解SQL语言,编写基本查询语句
|
3天前
|
SQL 缓存 数据库
sql 数据库优化
SQL数据库优化是一个复杂且关键的过程,涉及多个层面的技术和策略。以下是一些主要的优化建议: 查询语句优化: 避免全表扫描:在查询时,尽量使用索引来减少全表扫描,提高查询速度。 使用合适的子查询方式:子查询可能降低查询效率,但可以通过优化子查询的结构或使用连接(JOIN)替代子查询来提高性能。 简化查询语句:避免不必要的复杂查询,尽量使SQL语句简单明了。 使用EXISTS替代IN:在查询数据是否存在时,使用EXISTS通常比IN更快。 索引优化: 建立合适的索引:对于经常查询的列,如主键和外键,应创建相应的索引。同时,考虑使用覆盖索引来进一步提高性能。 避免过多的索引:虽然索引可以提高查询
|
3天前
|
SQL XML 数据库
sql导入数据库命令
在SQL Server中,数据库导入可通过多种方式实现:1) 使用SSMS的“导入数据”向导从各种源(如Excel、CSV)导入;2) BULK INSERT语句适用于导入文本文件;3) bcp命令行工具进行批量数据交换;4) OPENROWSET函数直接从外部数据源(如Excel)插入数据。在操作前,请记得备份数据库,并可能需对数据进行预处理以符合SQL Server要求。注意不同方法可能依版本和配置而异。
|
10天前
|
SQL 安全 网络安全
IDEA DataGrip连接sqlserver 提示驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接的解决方法
IDEA DataGrip连接sqlserver 提示驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接的解决方法
22 0
|
11天前
|
SQL 数据库
数据库SQL语言实战(二)
数据库SQL语言实战(二)

热门文章

最新文章