使用INSERT

时间:2017-07-05 12:02:43

标签: sql sql-server sql-server-2008 type-conversion

我有一个充满数据的现有表,可以使用

创建
CREATE TABLE __EpisodeCost
(
    ActivityRecordID INT NOT NULL, 
    ActCstID NVARCHAR(15), 
    VolAmt FLOAT, 
    ActCnt FLOAT, 
    TotCst FLOAT, 
    ResCstID NVARCHAR(50)
);

这来自我无法控制的Feed,我想将其转换为我自己的EpisodeCost

版本
CREATE TABLE EpisodeCostCtp
(
    ActivityRecordID INT NOT NULL, 
    ActCstID NVARCHAR(6), 
    ResCstID NVARCHAR(7), 
    ActCnt NVARCHAR(7), 
    TotCst DECIMAL(18, 8) 
);

现在,我遇到的问题是转换。我可以执行查询

SELECT 
    ActivityRecordID, 
    Cast(ActCstID AS NVARCHAR(6)), 
    Cast(ResCstID AS NVARCHAR(7)), 
    Cast(LTRIM(STR(ActCnt, 10)) AS NVARCHAR(7)), 
    Cast(TotCst AS DECIMAL(18, 8)) 
FROM __EpisodeCostCtp;

然后,当我尝试执行

时,它会提供数据
INSERT INTO EpisodeCostCtp 
    (
        ActivityRecordID, 
        ActCstID, 
        ResCstID, 
        ActCnt, 
        TotCst 
    ) 
SELECT 
    ActivityRecordID, 
    Cast(ActCstID AS NVARCHAR(6)), 
    Cast(ResCstID AS NVARCHAR(7)), 
    Cast(LTRIM(STR(ActCnt, 10)) AS NVARCHAR(7)), 
    Cast(TotCst AS DECIMAL(18, 8)) 
FROM __EpisodeCostCtp;

我得到了

  

Msg 8115,Level 16,State 8,Line 102   算术溢出错误将数字转换为数据类型数字。   声明已经终止。

为什么我SELECT可以使用相关的强制转型,但是不能INSERT进入目标表?

编辑。我还是不知道这里发生了什么。

根据Serg的建议,我试图找到有问题的记录,但查询

SELECT 
    ActivityRecordID, 
    Cast(ActCstID AS NVARCHAR(6)), 
    Cast(ResCstID AS NVARCHAR(7)), 
    Cast(LTRIM(STR(ActCnt, 10)) AS NVARCHAR(7)), 
    Cast(TotCst AS DECIMAL(18, 8))      
FROM __EpisodeCostCtp
WHERE TotCst > 9.999999999999999e9;

返回零记录。更改为9.999999999999999e8,转换/转换发生错误。我让scince更改了INSERT查询以使用DECIMAL(36, 18),现在插入成功,但我仍然没有更聪明。很明显,我对演员阵容施加了限制,但为什么SELECT有效且INSERT失败,我仍然不知道。

3 个答案:

答案 0 :(得分:3)

这是您可能想要尝试的溢出问题

{{1}}

来自https://docs.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql

  

当INSERT语句遇到算术错误时(溢出,   在表达期间发生的除以零或域错误   评估时,数据库引擎处理这些错误,就像SET一样   ARITHABORT设置为ON。批处理已停止,并显示错误消息   回。在SET ARITHABORT和SET的表达式评估期间   如果是INSERT,DELETE或UPDATE语句,则ANSI_WARNINGS为OFF   遇到算术错误,溢出,被零除或域   错误,SQL Server插入或更新NULL值。如果是目标   column不可为空,插入或更新操作失败并且用户   收到错误。

答案 1 :(得分:0)

我相信在你的TotCst列中的值大于DECIMAL(18,8)。 如果目标类型不够大,则SQL SERVER的2008版本将获得舍入结果。但它无法插入,因为该表仅接受精确值。

您可以在SQL SERVER 2012上看到我的两个查询的结果:

 DECLARE @float FLOAT 
 SET @float = 12345678911.12
 SELECT CAST(@float AS decimal(18,8))

结果: 将float转换为数值数据类型时发生算术溢出错误。

使用DECIMAL(19,8)进行相同的查询:

 DECLARE @float FLOAT 
 SET @float = 12345678911.12
 SELECT CAST(@float AS decimal(19,8))

结果:1​​2345678911.12000100

编辑:检查您的查询工具是否获取所有记录。如果没有,可能在其余记录中有一些值大于DECIMAL(18.8)

答案 2 :(得分:0)

要查找导致问题的行,请尝试

SELECT *       
FROM __EpisodeCostCtp
WHERE TotCst > 9.999999999999999e9;