Reputation: 23833
I have an existing table full of data, which can be created using
CREATE TABLE __EpisodeCost
(
ActivityRecordID INT NOT NULL,
ActCstID NVARCHAR(15),
VolAmt FLOAT,
ActCnt FLOAT,
TotCst FLOAT,
ResCstID NVARCHAR(50)
);
This comes from a feed I have no control over and I want to convert this to my own version called EpisodeCost
CREATE TABLE EpisodeCostCtp
(
ActivityRecordID INT NOT NULL,
ActCstID NVARCHAR(6),
ResCstID NVARCHAR(7),
ActCnt NVARCHAR(7),
TotCst DECIMAL(18, 8)
);
Now, the problem I am having is with conversions. I can execute the query
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;
and it provides data, however, when I try to execute
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;
I get
Msg 8115, Level 16, State 8, Line 102 Arithmetic overflow error converting numeric to data type numeric. The statement has been terminated.
Why can I SELECT
using the relevant casts, but then cannot INSERT
into the target table?
Edit. I still don;t fully know what is occurring here.
As per Serg's recommendations, I have attempted to locate the problematic records but the query
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;
returns zero records. Changing to 9.999999999999999e8 does, and the conversion/cast happens with out error. I have scince changed the INSERT
query to use DECIMAL(36, 18)
and now the insert succeeds, but I am still none the wiser. Clearly I was hitting a limit on the cast, but why SELECT
works and INSERT
fails, I still don't know.
Upvotes: 4
Views: 1320
Reputation: 10875
as is an overflow issue you might want to try
SET ARITHABORT OFF
from https://learn.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql
When an INSERT statement encounters an arithmetic error (overflow, divide by zero, or a domain error) occurring during expression evaluation, the Database Engine handles these errors as if SET ARITHABORT is set to ON. The batch is stopped, and an error message is returned. During expression evaluation when SET ARITHABORT and SET ANSI_WARNINGS are OFF, if an INSERT, DELETE or UPDATE statement encounters an arithmetic error, overflow, divide-by-zero, or a domain error, SQL Server inserts or updates a NULL value. If the target column is not nullable, the insert or update action fails and the user receives an error.
Upvotes: 3
Reputation: 22811
To find rows which cause the problem try
SELECT *
FROM __EpisodeCostCtp
WHERE TotCst > 9.999999999999999e9;
Upvotes: 0
Reputation: 2469
I believe that in your TotCst column has values bigger than DECIMAL(18,8). And the version 2008 of SQL SERVER gets a rounded result if the destination type is not large enough. But it can't insert because the table accepts exact values only.
You can see the result of my two queries on SQL SERVER 2012 :
DECLARE @float FLOAT
SET @float = 12345678911.12
SELECT CAST(@float AS decimal(18,8))
Result : An arithmetic overflow error occurred when converting float to numeric data type.
the same query with DECIMAL(19,8) instead :
DECLARE @float FLOAT
SET @float = 12345678911.12
SELECT CAST(@float AS decimal(19,8))
Result : 12345678911.12000100
EDIT : Check if your query tool fetchs all records. If not, maybe among the rest of records there are some values bigger than DECIMAL(18.8)
Upvotes: 0