我不确定这是否可行,但现在就去了。
我有以csv格式存储的财务数据。遗憾的是,这些数据在美元领域没有任何小数点。所以$ 100.00存储为' 00000010000'。它也存储为字符串。在我当前的设置中,我将csv文件上传到一个临时表,所有列都设置为varchar(x)。
我知道如果我尝试将此值插入整数列,它会自动将其转换为10000的整数类型,但这意味着我错过了我的小数位。
无论如何,我可以创建一个表,以便插入一个存储为字符串或整数的整数自动将其转换为小数点后面的2位小数???? EX:' 000010000' - > 100.00
我知道我可以将列强制转换为十进制并将现有值除以100 ....但此表有100多列,其中60列需要重铸。这也只是表1中的第1步。我想避免创建命令来单独更改相关列。并非所有包含数字的列都需要小数处理。
答案 0 :(得分:0)
为什么不只是一个基本的查询?你必须分两步进行数学运算,因为'00000010000'很大,适合基本数字。但是乘以1会隐式转换为int然后很容易除以100.注意它需要是100.0所以它会隐式地将它转换为数字而不是int。以下是几个示例值。
select convert(numeric(9, 2), ('00000010000' * 1) / 100.0)
select convert(numeric(9, 2), ('00000010123' * 1) / 100.0)
答案 1 :(得分:0)
只是一个小帮助程序存储过程,将导入的表转换为所需的格式。
指定要创建的导入表名,转换后的表名,以及不需要转换的以逗号分隔的列列表。
MS SQL Server 2014架构设置:
create table source (
id int not null identity(1,1),
c1 varchar(100) not null,
c2 varchar(100) not null,
c3 varchar(100) not null,
c4 varchar(100) not null,
c5 varchar(100) not null,
c6 varchar(100) not null
);
insert source (c1, c2, c3, c4, c5, c6) values
('a', '000001000', '000001000', '000001000', '000001000', 'b'),
('c', '000002001', '000002002', '000002003', '200020002', 'd'),
('e', '000003002', '000003002', '000003003', '300030003', 'f'),
('g', '000004003', '000004002', '000004003', '400040004', 'h'),
('i', '000005004', '000005002', '000005003', '500050005', 'j')
;
create procedure convert_table
@source varchar(max),
@dest varchar(max),
@exclude_cols varchar(max)
as
begin
declare
@sql varchar(max) = 'select ',
@col_name varchar(max)
if @exclude_cols not like ',%' set @exclude_cols = ',' + @exclude_cols
if @exclude_cols not like '%,' set @exclude_cols = @exclude_cols + ','
declare c cursor for
select column_name
from information_schema.columns
where table_name = @source
open c
fetch next from c into @col_name
while @@fetch_status = 0
begin
if @exclude_cols like '%,' + @col_name + ',%'
set @sql = @sql + @col_name + ','
else
set @sql = @sql + 'convert(numeric(11, 2), ' + @col_name + ') / 100 as ' + @col_name + ','
fetch next from c into @col_name
end
close c
deallocate c
set @sql = substring(@sql, 1, len(@sql) -1)
set @sql = @sql + ' into ' + @dest + ' from ' + @source
--print(@sql)
exec(@sql)
end
;
exec convert_table @source = 'source', @dest = 'dest', @exclude_cols = 'id,c1,c6'
查询1 :
select * from dest
<强> Results 强>:
| id | c1 | c2 | c3 | c4 | c5 | c6 |
|----|----|-------|-------|-------|------------|----|
| 1 | a | 10 | 10 | 10 | 10 | b |
| 2 | c | 20.01 | 20.02 | 20.03 | 2000200.02 | d |
| 3 | e | 30.02 | 30.02 | 30.03 | 3000300.03 | f |
| 4 | g | 40.03 | 40.02 | 40.03 | 4000400.04 | h |
| 5 | i | 50.04 | 50.02 | 50.03 | 5000500.05 | j |
答案 2 :(得分:0)
所以我没有找到我希望的过于简单的答案,但我确实找到了另一种方法来实现我的目标。如果我将所有应该有小数位的列设置为十进制类型,那么我可以使用系统表和(Tsql?)来修改十进制类型的所有列,使其等于自身/ 100.0。
DECLARE @tableName varchar(10)
SET @tableName = 'test21'
DECLARE @sql VARCHAR(MAX)
SET @sql = ''
SELECT @sql = @sql + 'UPDATE ' + @tableName + ' SET ' + c.name + ' = ' + c.name + '/100.0 ;'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE t.name = @tableName AND y.name IN ('decimal')
exec(@sql)
我必须根据系统表中的信息在SQL中动态构造命令,然后执行它。 。