SELECT Query - String or binary data would be truncated. The statement has been terminated - sql

Query below gives the error above
SELECT * FROM dbo.DoSRF_001 ( 001 ,0 ,-1 ,0 ,'2014-01-01' )
Funny thing is, anything other than '2014-01-01' runs fine. Like '2015-01-01' or '2013-01-01'.
Function has hundreds of lines. But I thought it might have an easy solution.
Here are the parameters
CREATE FUNCTION [dbo].[DoSRF_001]
(
#FirmNo int = NULL
,#DeptNo int = NULL
,#SiteNo int = NULL
,#UnitNo int = NULL
,#PerdBeg datetime = NULL
)

I believe the "String or Binary data would be truncated" error is only producte when trying to INSERT or UPDATE data - I would check the places where you are actually updating a table and see what column values could have strings larger than the column width (e.g. if they're pulled from a different table).

Related

How to convert from nchar to decimal in SQL?

I have 2 tables(source and destination) which are respectively NOR_LABOR and ALL_LABOR_DETAILS. In the source table(NOR_LABOR) there is a column "feet_produced" with the data type "nchar(10)". In the destination table(ALL_LABOR_DETAILS) there's a column "labor_feet_produced" with the data type "decimal(18,4)". I want to convert the "feet_produced" from nchar(10) to decimal(18,4) and paste it in the "ALL_LABOR_DETAILS" table's "labor_feet_produced" column.
I have found a code regarding a simillar issue but did not do the exact as I need to do, following is that code snippet :
Select feet_produced AS feet_produced_s, CASE WHEN Isnumeric(feet_produced) = 1
THEN CONVERT(DECIMAL(18,2),feet_produced)
ELSE 0 END AS feet_produced
INTO [MES_DEV].[dbo].[ALL_LABOR_DETAILS]
from [dbo].[NOR_LABOR]
Thank you!
There are values that will test true for IS_NUMERIC, but will fail to convert to decimal.
Instead, use TRY_CONVERT which will return either the successfully-converted-to-decimal value, or a NULL when it fails. (You can then COALESCE to zero to get your desired result).
Here is a short example set of values, using TRY_CONVERT:
SELECT
TryConvert = COALESCE(TRY_CONVERT(decimal(18,4),TestValues),0)
FROM (
VALUES('10.6'),
('ten'),
('7d2'),
('10000000000'),
('10.00000001')
) AS x(TestValues);
The same set of values using your example code will throw an error:
SELECT
IsNumericCase = CASE
WHEN Isnumeric(TestValues) = 1
THEN CONVERT(DECIMAL(18,2),TestValues)
ELSE 0
END
FROM (
VALUES('10.6'),
('ten'),
('7d2'),
('10000000000'),
('10.00000001')
) AS x(TestValues);
This error is returned because 7d2 is numeric, but cannot be converted to decimal.
Msg 8114, Level 16, State 5, Line 14
Error converting data type varchar to numeric.
Im not sure what the issue is with the code that dose not work for you.
But here is how I would do it with a small change in the statement that you just post it.
insert into[MES_DEV].[dbo].[ALL_LABOR_DETAILS](labor_feet_produced)
select CONVERT(DECIMAL(18, 4), feet_produced) AS feet_produced_s from[dbo].[NOR_LABOR]

Update Accumulated Value with CTE error because of decimal datatype (SQL)

I am trying to get the accumulated value of the column MontanteRecuperacao into montanterecuperacao_acumulada, by date and contract.
But the decimal datatype is becoming a problem and I don't know why, this works when the variables are of INT type.
This is the error message
Msg 4187, Level 16, State 1, Procedure spCalculaRecuperacao, Line 123
Data type decimal of receiving variable cannot store all values of the data type decimal of column 'montanterecuperacao_acumulada' without data loss.
Code:
DECLARE #MontanteRecuperacao_running DECIMAL,
#montanterecuperacao_acumulada_running DECIMAL,
#Contrato VARCHAR(10) = '' ;
WITH CTE AS
(
SELECT TOP 100 PERCENT
MontanteRecuperacao, montanterecuperacao_acumulada, ContratoId
FROM
MovimentoRecuperacao
ORDER BY
[ContratoId], [DtReferencia] DESC
)
UPDATE CTE
SET #montanterecuperacao_acumulada_running = montanterecuperacao_acumulada =
CASE
WHEN #Contrato <> ContratoId
THEN montanterecuperacao_acumulada
ELSE #montanterecuperacao_acumulada_running - #MontanteRecuperacao_running
END,
#MontanteRecuperacao_running = MontanteRecuperacao,
#Contrato = ContratoId
You've declared your DECIMAL parameters without specifying precision or scale:
#MontanteRecuperacao_running DECIMAL , #montanterecuperacao_acumulada_running DECIMAL
The default values are DECIMAL(18,0), which is essentially an integer. In order to get the behavior you desire, you'll need to assess your data for proper values to assign.

Conversion failed when converting the varchar value 'durationms' to data type int

I am getting this error when I run the case statement below. I think I have to convert at some point, but not sure where or how.
update [092018]
set duration1 = duration
where duration1 is null
and (durationms > 100 and durationms < 1000)
Conversion failed when converting the varchar value 'durationms' to data type int
It sounds like your duarationms column is text of some sort. You may try casting it to integer:
UPDATE [092018]
SET duration1 = duration
WHERE duration1 IS NULL AND
CAST(durationms AS int) > 100 AND CAST(durationms AS int) < 1000;
Note that for brevity you could have written the WHERE clause as:
WHERE duration1 IS NULL AND CAST(durationms AS int) BETWEEN 101 AND 999;
If you plan on doing arithmetic with the data contained in durationms, then consider making it a numeric/integer column.
Edit:
If the above query is still not working, then your data might be in even worse shape than we thought. There could be non numeric data in the durationms column. To flag out records which can't be cast to integer, use the following query:
SELECT *
FROM [092018]
WHERE TRY_CONVERT(int, durationms) IS NULL;
Any records returned should have durationms values which can't be coerced into integers.
If your version of SQL Server does not support TRY_CONVERT, then here is another option:
SELECT *
FROM [092018]
WHERE durationms LIKE '%[^0-9]%';

Why am I unable to convert datatype to return blank cells for values of 0 or NULL?

I am currently trying to return '' for values that are either NULL or 0, but am unable to do so:
select isnull(cast(sec_column as varchar(10)),'')
sec_column is Numeric
The above produces the follow sql error:
"Arithmetic overflow error converting numeric to data type varchar"
Additionally, I have tried something simpler along the lines of an ISNULL to achieve this, but to no avail:
select isnull(sec_column,'')
I assume that I should be able to cast as a string value and return blank. Any insight into this would be much appreciated!
That error for the given code would indicate you need a larger varchar():
select isnull(cast(sec_column as varchar(39)),'')
declare #val numeric(38,2) = '123456789123456789123456789123456789.12'
/* works fine */
select convert(varchar(39),#val)
select convert(varchar(10),#val)
/* Arithmetic overflow error converting numeric to data type varchar. */
rextester demo: http://rextester.com/GMYUUN51608
Perhaps this can help.
Assuming sec_column is a numeric, and you want to show zeros and nulls as ""
select isnull(cast(nullif(sec_column,0) as varchar(10)),'')
Example
Declare #YourTable Table (sec_column int)
Insert Into #YourTable Values
(1)
,(null)
,(25)
,(0)
select *
,AsString = isnull(cast(nullif(sec_column,0) as varchar(10)),'')
From #YourTable
Returns
sec_column AsString
1 1
NULL
25 25
0

TSQL error on insert "String or binary data would be truncated"

In the code below I am inserting values into a table and getting the error "String or binary data would be truncated."
My table definition:
CREATE TABLE urs_prem_feed_out_control
(
bd_pr_cntl_rec_type char(7) NULL ,
pd_pr_cntl_acctg_dte char(6) NULL ,
bd_pr_cntl_run_dte char(10) NULL ,
bd_pr_cntl_start_dte char(10) NULL ,
bd_pr_cntl_end_dte char(10) NULL ,
bd_pr_cntl_rec_count char(16) NULL ,
bd_pr_tot_premium char(16) NULL ,
bd_pr_tot_commission char(16) NULL ,
fd_ctl_nbr integer NOT NULL
)
DECLARE #cur_fd_ctl_nbr INT = 2,
#acctg_cyc_ym_2 CHAR(6) = '201402',
#rundate CHAR (10) = CONVERT(CHAR(10),GETDATE(),101),
#cycle_start_dt DATETIME = '2014-02-17',
#cycle_end_dt DATETIME = '2014-02-24',
#record_count INT = 24704,
#tot_pr_premium DECIMAL(18,2) = 476922242,
#tot_pr_comm DECIMAL(18,2) = 2624209257
Insert code (I've declared the variables as constant values for testing, I took these values from what they were at runtime):
INSERT INTO urs_prem_feed_out_control
SELECT fd_ctl_nbr = #cur_fd_ctl_nbr,
bd_pr_cntl_rec_type = 'CONTROL',
bd_pr_cntl_acctg_dte = #acctg_cyc_ym_2,
bd_pr_cntl_run_dte = #rundate,
bd_pr_cntl_start_dte = CONVERT(CHAR(10),#cycle_start_dt,101),
bd_pr_cntl_end_dte = CONVERT(CHAR(10),#cycle_end_dt,101),
bd_pr_cntl_rec_count = RIGHT('0000000000000000' + RTRIM(CONVERT(CHAR(16),#record_count)),16),
bd_pr_tot_premium = CASE
WHEN #tot_pr_premium < 0
THEN '-' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(#tot_pr_premium)*100))),18),1,15)
ELSE
'+' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(#tot_pr_premium)*100))),18),1,15)
END,
bd_pr_tot_commission = CASE
WHEN #tot_pr_comm < 0
THEN '-' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(#tot_pr_comm)*100))),18),1,15)
ELSE
'+' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(#tot_pr_comm)*100))),18),1,15)
END
When I look at each value individually it seems like they are all within the variable length constraints of the table. Any idea why I'm getting this error?
Thanks!
The problem with your insert query is THE ORDER OF INSERTION :
SELECT fd_ctl_nbr = #cur_fd_ctl_nbr,
This column must be defined at the last in the INSERT as its the last column defined in the create table script.
Change your query to this:
INSERT INTO #urs_prem_feed_out_control (fd_ctl_nbr, bd_pr_cntl_rec_type, pd_pr_cntl_acctg_dte, bd_pr_cntl_run_dte, bd_pr_cntl_start_dte, bd_pr_cntl_end_dte, bd_pr_cntl_rec_count, bd_pr_tot_premium, bd_pr_tot_commission)
SELECT fd_ctl_nbr = #cur_fd_ctl_nbr,
bd_pr_cntl_rec_type = 'CONTROL',
bd_pr_cntl_acctg_dte = #acctg_cyc_ym_2,
bd_pr_cntl_run_dte = #rundate,
bd_pr_cntl_start_dte = CONVERT(CHAR(10),#cycle_start_dt,101),
bd_pr_cntl_end_dte = CONVERT(CHAR(10),#cycle_end_dt,101),
bd_pr_cntl_rec_count = RIGHT('0000000000000000' + RTRIM(CONVERT(CHAR(16),#record_count)),16),
bd_pr_tot_premium = CASE
WHEN #tot_pr_premium < 0
THEN '-' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(#tot_pr_premium)*100))),18),1,15)
ELSE
'+' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(#tot_pr_premium)*100))),18),1,15)
END,
bd_pr_tot_commission = CASE
WHEN #tot_pr_comm < 0
THEN '-' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(#tot_pr_comm)*100))),18),1,15)
ELSE
'+' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(#tot_pr_comm)*100))),18),1,15)
END
Doing this would also work. Notice that the first column here in the SELECT within the INSERT is just the way you have provided in your question.
See this here-> http://sqlfiddle.com/#!3/0e09b/1
Hope this helps!!!
This is why you should never write an insert statement without specifying the columns. Since you did not, it wil try to put the data in the columns in the order they are in the table which is not at all the order you have them in.
Another thing that can happen when you get this sort of message (but which I don't think applies in your case, I include it for people searching later) is that the eeror is actually coming from a trigger and not the main insert.
Finally a note on database design, you should not be using char for dates, you should be using date fields. You cannot do date math on a char field and it will accept incorrect date values like feb30, 2014. It is always a bad idea to store dates as anything except date or datetime values. In general char should only be used rarely when a column will always have the same number of characters (like a 2 column state abbreviation), it should not be used as the default datatype. You need to do a better job of defining datatypes that match the type and size of data being stored. You can run into problems with queries as 'VA' is not the same thing as 'VA '. In general my experience is that less than 1 % of all database fields should be Char.
I think it may be beneficial to double check your work. Consider the following example code:
DECLARE #Table TABLE (Name NVARCHAR(1))
INSERT INTO #Table (Name) SELECT 'ab'
INSERT INTO #Table (Name) SELECT SUBSTRING('ab',1,2)
INSERT INTO #Table (Name) SELECT RIGHT('abc',2)
All yield the following: String or binary data would be truncated.