I wrote the store procedure which should return the values like-
J1
J2
J3
I have table named Journal_Entry. When the row count of the table is 0, it gives the result J1 but as the row count increases it shows the error-
"Conversion failed when converting the varchar value 'J' to data type int."
#here the Voucher_No is the column for the result to be saved.
The code is like-
CREATE PROC [dbo].[getVoucherNo]
AS
BEGIN
DECLARE @Prefix VARCHAR(10)='J'
DECLARE @startFrom INT=1
DECLARE @maxCode VARCHAR(100)
DECLARE @sCode INT
IF((SELECT COUNT(*) FROM dbo.Journal_Entry) > 0)
BEGIN
SELECT @maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(@startFrom)+1,LEN(Voucher_No)- LEN(@Prefix)) AS INT)) AS varchar(100)) FROM dbo.Journal_Entry;
SET @sCode=CAST(@maxCode AS INT)
SELECT @Prefix + LEN(CAST(@maxCode AS VARCHAR(10))+1) + CAST(@maxCode AS VARCHAR(100))
END
ELSE
BEGIN
SELECT(@Prefix + CAST(@startFrom AS VARCHAR))
END
END
![]()
Devart
118k22 gold badges162 silver badges184 bronze badges
asked Jul 10, 2013 at 10:14
4
The problem located on the following line
SELECT @Prefix + LEN(CAST(@maxCode AS VARCHAR(10))+1) + CAST(@maxCode AS VARCHAR(100))
Use this instead
SELECT @Prefix + CAST(LEN(CAST(@maxCode AS VARCHAR(10))+1) AS VARCHAR(100)) + CAST(@maxCode AS VARCHAR(100))
Full Code:
CREATE PROC [dbo].[getVoucherNo]
AS
BEGIN
DECLARE @Prefix VARCHAR(10)='J'
DECLARE @startFrom INT=1
DECLARE @maxCode VARCHAR(100)
DECLARE @sCode INT
IF((SELECT COUNT(*) FROM dbo.Journal_Entry) > 0)
BEGIN
SELECT @maxCode = CAST(MAX(CAST(SUBSTRING(VoucharNo,LEN(@startFrom)+1,LEN(VoucharNo)- LEN(@Prefix)) AS INT))+1 AS varchar(100)) FROM dbo.Journal_Entry;
SET @sCode=CAST(@maxCode AS INT)
SELECT @Prefix + CAST(LEN(CAST(@maxCode AS VARCHAR(10))+1) AS VARCHAR(100)) + CAST(@maxCode AS VARCHAR(100))
END
ELSE
BEGIN
SELECT(@Prefix + CAST(@startFrom AS VARCHAR))
END
END
answered Jul 10, 2013 at 11:31
2
I got the same error message. In my case, it was due to not using quotes.
Although the column was supposed to have only numbers, it was a Varchar column, and one of the rows had a letter in it.
So I was doing this:
select * from mytable where myid = 1234
While I should be doing this:
select * from mytable where myid = '1234'
If the column had all numbers, the conversion would have worked, but not in this case.
answered Feb 11, 2014 at 14:03
![]()
live-lovelive-love
46.1k22 gold badges227 silver badges196 bronze badges
Your problem seams to be located here:
SELECT @maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(@startFrom)+1,LEN(Voucher_No)- LEN(@Prefix)) AS INT)) AS varchar(100)) FROM dbo.Journal_Entry;
SET @sCode=CAST(@maxCode AS INT)
As the error says, you’re casting a string that contains a letter ‘J’ to an INT which for obvious reasons is not possible.
Either fix SUBSTRING or don’t store the letter ‘J’ in the database and only prepend it when reading.
answered Jul 10, 2013 at 10:18
Jakub KoneckiJakub Konecki
45.3k7 gold badges87 silver badges126 bronze badges
The line
SELECT @Prefix + LEN(CAST(@maxCode AS VARCHAR(10))+1) + CAST(@maxCode AS VARCHAR(100))
is wrong.
@Prefix is 'J' and LEN(...anything...) is an int, hence the type mismatch.
It seems to me, you actually want to do,
SELECT
@maxCode = MAX(
CAST(SUBSTRING(
Voucher_No,
@startFrom + 1,
LEN(Voucher_No) - (@startFrom + 1)) AS INT)
FROM
dbo.Journal_Entry;
SELECT @Prefix + CAST(@maxCode AS VARCHAR(10));
but, I couldn’t say. If you illustrated before and after data, it would help.
answered Jul 10, 2013 at 10:20
JodrellJodrell
34.4k5 gold badges85 silver badges123 bronze badges
Try this one —
CREATE PROC [dbo].[getVoucherNo]
AS BEGIN
DECLARE
@Prefix VARCHAR(10) = 'J'
, @startFrom INT = 1
, @maxCode VARCHAR(100)
, @sCode INT
IF EXISTS(
SELECT 1
FROM dbo.Journal_Entry
) BEGIN
SELECT @maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(@startFrom)+1,ABS(LEN(Voucher_No)- LEN(@Prefix))) AS INT)) AS varchar(100))
FROM dbo.Journal_Entry;
SELECT @Prefix +
CAST(LEN(LEFT(@maxCode, 10) + 1) AS VARCHAR(10)) + -- !!! possible problem here
CAST(@maxCode AS VARCHAR(100))
END
ELSE BEGIN
SELECT (@Prefix + CAST(@startFrom AS VARCHAR))
END
END
answered Jul 10, 2013 at 10:20
![]()
DevartDevart
118k22 gold badges162 silver badges184 bronze badges
1
- Remove From My Forums
-
Question
-
Dear All,
When I am firing a below query I am getting the error
SELECT
Empcode,
Date_of_Joining,
LastWorkingDate,
Tenure,
CASE WHEN CAST( Tenure AS INTEGER) =1 THEN ‘THREE’ ELSE Tenure END TENFROM #TEMP
tenure I AM getting bu substracting lastworking date to date of joining
Error:-
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value ‘THREE’ to data type int.Regards,
Vipin jha
Thankx & regards, Vipin jha MCP
-
Changed type
Monday, January 7, 2013 4:41 PM
Question rather than discussion
-
Changed type
Answers
-
Try this,
The problem is you are trying to mix int and varchar datatypes together.
SELECT Empcode, Date_of_Joining, LastWorkingDate, Tenure, CASE WHEN CAST( Tenure AS INTEGER) =1 THEN 'THREE' ELSE Convert(Varchar(100),Tenure) END TEN FROM #TEMP
Regards
satheesh-
Proposed as answer by
Kalman Toth
Monday, January 7, 2013 6:40 PM -
Marked as answer by
Allen Li — MSFT
Monday, January 14, 2013 5:59 AM
-
Proposed as answer by
-
Try
SELECT Empcode, Date_of_Joining, LastWorkingDate, Tenure, CASE WHEN Tenure NOT LIKE '%[^0-9]%' then when CAST( Tenure AS INTEGER) =1 THEN 'THREE' else cast(Tenure as varchar(20)) end ELSE cast(Tenure as varchar(20)) END As TEN
For every expert, there is an equal and opposite expert. — Becker’s Law
My blog
-
Proposed as answer by
Kalman Toth
Monday, January 7, 2013 6:40 PM -
Marked as answer by
Allen Li — MSFT
Monday, January 14, 2013 5:59 AM
-
Proposed as answer by
If you are seeing an error similar to “Conversion failed when converting the varchar value ‘something’ to data type int.”, I find the easiest method for identifying a solution to the problem is to analyze the data causing the error.
To illustrate how I identify bad data when making conversions, consider the environment setup below:
DECLARE @table TABLE (id VARCHAR(4));
INSERT INTO @table (id)
VALUES ('1' -- id - int
)
, ('NULL')
, (NULL);
We have a simple table with a single column. The column type is a varchar(4) that allows NULL entries. We have inserted a 1, NULL, and the word “NULL”. Here’s what our table looks like:
-- Step 1, see what the values look like. SELECT * FROM @table;

Your table and data set will probably be more complicated than our example table here. The methodology still remains true however to identifying our bad data. Let’s start by seeing the error our table produces.
-- Step 2, See how conversion errors out. SELECT CAST(id AS INT) FROM @table;

Now to identify what is causing that problem, I’m going to use the TRY_CAST function wrapped in a CASE WHEN statement. I’ll persist this data set in memory with a CTE and then select the results filtered by the data sets giving me troubles.
-- Step 3, how do we find out what is causing the error? ; WITH cte AS ( SELECT CASE WHEN TRY_CAST(id AS INT) IS NULL THEN id ELSE 'BadData' END AS result FROM @table ) SELECT * FROM cte WHERE result <> 'BadData';

As we can see, it was the string “NULL” instead of the other NULL entry that was causing the conversion error. This is because the word “NULL” and a NULL entry are two very different things. I’m not going to dive too much into that in this post, but I do plan on discussing this topic later!
So what if I wanted to leave the bad data out of the equation and convert only the good data?
-- Step 4, convert only the good data. ; WITH cte AS ( SELECT CASE WHEN TRY_CAST(id AS INT) IS NOT NULL THEN id ELSE 'BadData' END AS result FROM @table ) SELECT cast(result as INT) as 'ConvertedValue' FROM CTE WHERE result <> 'BadData'

The idea here is that when the TRY_CAST value IS NOT NULL, then we display the ID value. We are reversing the CASE WHEN piece here to identify the good data now so we can easily filter out the bad data. This allows us to filter the results and perform a CAST on the values. A similar effect could be achieved by attaching the CASE WHEN statement to the subqueries WHERE clause and also adding the result for BadData filter, thereby negating the CTE. This can potentially cause a massive performance problem, so use with caution.
The reason for the need to have the CASE WHEN in the WHERE clause or utilizing a CTE (or some other method to hold a result set) is due to the logical order of operations performed by SQL. SQL evaluates the following clauses in this order:
- FROM
- WHERE
- GROUP BY
- HAVING
- SELECT
- ORDER BY
This means our query analyzes the WHERE clause first before the SELECT occurs. This means the below query would be invalid:
SELECT CASE WHEN TRY_CAST(id AS INT) IS NOT NULL THEN id ELSE 'BadData' END AS result FROM @table WHERE result = 'BadData'
The column name and CASE WHEN function don’t even process before we begin to query the table variable and attempt a predicate filter on the column ‘result’. Here’s a valid example of filtering logic in the WHERE clause with a CASE WHEN.
SELECT CASE WHEN TRY_CAST(id AS INT) IS NOT NULL THEN id ELSE 'BadData' END AS result FROM @table WHERE 'BadData' <> CASE WHEN TRY_CAST(id AS INT) IS NOT NULL THEN id ELSE 'BadData' END
Again, this can have huge performance ramifications. In my experience, this generally can cause an index scan depending on your index setup. So as always, evaluate the situation and think critically about the route you want to take to solve the problem. Measure, tweak, record, compare, repeat.
Ideally, the best way to resolve the issue is to create constraints that force consistency and reliability in your data. The next best from there is going in and fixing your data sets periodically as issues appear.
I have added in a form for feedback, it would be very helpful if you would take a few minutes to fill this out. My goal is to adjust the content to best help others resolve their problems.
- Remove From My Forums
-
Question
-
Hi, I am working on a report which is off of survey information and I am using dynamic pivot on multiple columns.
I have questions like Did you use this parking tag for more than 250 hours? If yes specify number of hours.
and the answers could be No, 302, 279, No and so on….All these answers are of varchar datatype and all this data comes from a partner application where we consume this data for internal reporting.
When I am doing dynamic pivot I get the below error.
Error: Conversion failed when converting the varchar value ‘No’ to data type int.
Query
DECLARE @Cols1 VARCHAR(MAX), @Cols0 VARCHAR(MAX), @Total VARCHAR(MAX), @SQL VARCHAR(MAX) SELECT @Cols1 = STUFF((SELECT ', ' + QUOTENAME(Question) FROM Question GROUP BY Question FOR XML PATH('')),1,2,'') SELECT @Cols0 = (SELECT ', COALESCE(' + QUOTENAME(Question) + ',0) as ' + QUOTENAME(Question) FROM Question GROUP BY Question FOR XML PATH('')) SET @SQL = 'SELECT QID, QNAME' + @Cols0 + ' FROM (SELECT QID, QNAME, ANSWERS, Question FROM Question) T PIVOT (MAX(ANSWERS) FOR Question IN ('+@Cols1+')) AS P' EXECUTE (@SQL)I am using SQL Server 2008 R2.
Please guide me to resolve this.
Thanks in advance……….
Ione
Answers
-
create table questions (QID int, QNAME varchar(50), ANSWERS varchar(500), Question varchar(50)) Insert into questions values(1,'a','b','c'), (2,'a2','b2','c2') DECLARE @Cols1 VARCHAR(MAX), @Cols0 VARCHAR(MAX), @Total VARCHAR(MAX), @SQL VARCHAR(MAX) SELECT @Cols1 = STUFF((SELECT ', ' + QUOTENAME(Question) FROM Questions GROUP BY Question FOR XML PATH('')),1,2,'') SELECT @Cols0 = (SELECT ', COALESCE(' + QUOTENAME(Question) + ',''0'') as ' + QUOTENAME(Question) FROM Questions GROUP BY Question FOR XML PATH('')) SET @SQL = 'SELECT QID, QNAME' + @Cols0 + ' FROM (SELECT QID, QNAME, ANSWERS, Question FROM Questions) T PIVOT (MAX(ANSWERS) FOR Question IN ('+@Cols1+')) AS P' EXECUTE (@SQL) drop table questions-
Marked as answer by
Monday, February 9, 2015 4:59 PM
-
Marked as answer by
Giff is almost right. The problem is that you’re trying to add a number to a string literal. Because of SQL’s type conversion rules, it tries to convert the string to a number in order to perform the addition.
You would need to convert the number to a string before concatenating it to the string literal:
SET @CUSTOMERIDS = 'AND VU_CRM_Customers.CustomerID = ' + CAST(@CustomerID As varchar(20))
But that’s not a good approach. Whilst you’re probably safe in this particular instance, since the parameters are either numbers or dates, using string concatenation to build a SQL query can leave you vulnerable to SQL Injection[^].
sp_executesql[^] gives you a much safer option: pass the parameters as parameters:
CREATE PROCEDURE SP_Customer(@FromDate date, @ToDate date, @AccessLevelCode nvarchar(30) = NULL, @UserID nvarchar(30) = NULL, @UserOrgBranchID int = NULL, @UserGroupID int = NULL, @CustomerID int = 0) AS BEGIN DECLARE @SQL nvarchar(max), @params nvarchar(max); DECLARE @AccessFilter nvarchar(max), @CustomerIDs nvarchar(max); SET NOCOUNT ON; SET @AccessFilter = dbo.fnGetAccessFilter(@AccessLevelCode, @UserID, @UserOrgBranchID, @UserGroupID); SET @CustomerIDs = CASE WHEN @CustomerID Is Null THEN N'' ELSE N'AND VU_CRM_Customers.CustomerID = @CustomerID' END; SET @SQL = N' DECLARE @Temp TABLE ( [Row] INT, Customer NVARCHAR(MAX), CustomerID int, TransactionType NVARCHAR(MAX), VoucherDate smalldatetime, VoucherNo NVARCHAR(MAX), AccountingDate datetime, Amount numeric(18,3), Debit numeric(18,3), Credit numeric(18,3), [OrgID] INT ); INSERT INTO @Temp SELECT ROW_NUMBER() OVER(PARTITION BY Customer ORDER BY CreatedDate) AS Row, * FROM ( SELECT CASE WHEN ISNULL(ISNULL(Mobile,Phone),'''') = '''' THEN Customer ELSE CONCAT(Customer,''('',ISNULL(Mobile,Phone),'')'') END AS Customer, ''Opening Balance'' AS TransactionType, AccountingDate AS VoucherDate, COALESCE(ACC_FinOpeningBalance.ReferenceNo, CONVERT(nvarchar,OpeningBalanceID)) AS VoucherNo, AccountingDate AS CreatedDate, CASE WHEN Dr > 0 THEN Dr ELSE Cr END AS Amount, Dr AS Debit, Cr AS Credit, ACC_FinOpeningBalance.OrgID FROM ACC_FinOpeningBalance INNER JOIN VU_CRM_Customers ON ACC_FinOpeningBalance.SLGroupCode = ''C'' AND ACC_FinOpeningBalance.SubledgerID = VU_CRM_Customers.CustomerID WHERE ACC_FinOpeningBalance.CreatedBy' + @AccessFilter + @CustomerIDs + N' UNION SELECT CASE WHEN ISNULL(ISNULL(Mobile,Phone),'''')='''' THEN Customer ELSE CONCAT(Customer,''('',ISNULL(Mobile,Phone),'')'') END AS Customer, ''Advance'' AS TransactionType, AdvanceDate AS VoucherDate, COALESCE(ACC_AdvanceReceived.ReferenceNo, CONVERT(nvarchar,AdvanceReceivedID)) AS VoucherNo, AdvanceDate AS CreatedDate, NetReceivable AS Amount, NetReceivable AS Debit, 0 AS Credit, ACC_AdvanceReceived.OrgID FROM ACC_AdvanceReceived INNER JOIN VU_CRM_Customers ON ACC_AdvanceReceived.AccountID = VU_CRM_Customers.CustomerID WHERE Customer IS NOT NULL AND ACC_AdvanceReceived.CreatedBy' + @AccessFilter + @CustomerIDs + N' ) ; SELECT *, (M.OpeningBalance + M.Debit - M.Credit) AS ClosingBalance FROM ( SELECT L.Row, L.Customer, L.TransactionType, L.VoucherDate, L.VoucherNo, L.AccountingDate, L.Amount, L.OrgID, ISNULL((SELECT SUM(Debit) - SUM(Credit) FROM @Temp AS O WHERE O.AccountingDate <= L.AccountingDate AND O.Customer = L.Customer AND O.Row < L.Row), 0) AS OpeningBalance, L.Debit, L.Credit FROM @Temp AS L WHERE L.AccountingDate >= @FromDate And L.AccountingDate < @ToDate ) As M ;'; SET @params = N'@FromDate date, @ToDate date, @CustomerID int'; EXEC sp_executesql @SQL, @params, @FromDate = @FromDate, @ToDate = @ToDate, @CustomerID = @CustomerID; print @SQL; END
NB: You can probably do something about the value returned from fnGetAccessFilter as well; but since I can’t see the code for that function, I can’t tell you.
NB2: Tidying up your dynamic query makes it obvious that you have several misplaced brackets. Once you’d fixed the conversion error, the next error would be a syntax error trying to execute your query. I think I’ve fixed it, but you should probably check.
NB3: Depending on which version of SQL Server you’re running, there is probably a much cleaner way to generate the running totals. If it’s 2012 or later, you can use the LAG function[^].
The Reason for this error is you are converting a varchar value to Int or Numeric or any Other datatype let us take a simple example
select CAST(‘abc’ as int)
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value ‘abc’ to data type int.
what we are doing in above query is changing the nvarchar value to int which is not possible that why it throw the error.
While working with TSQL Coding if you are adding some string value with alphanumeric field you could face the above problem if you have not written your query properly.
Take an Example where you want to show empidEmpsalary from employee table
for this we will create a table below
create table Employee1_error1
(Empid int identity (1,1) ,EmpName nvarchar(50),EmpSalary float)
insert into Employee1_error1 values(‘Amit’,’5000′),(‘Sumit’,’6000′),(‘Raj’,’8000′),(‘vijay’,’9000′),(‘suresh’,’10000′)
select * from Employee1_error1
now we want to display employee empidEmpsalary in same format we are concatenating the slash in between empidEmpsalary
like we want our result like
EmpIdEmpsalary
15000
26000 and so on ……….
now run the below query
select cast(empid+»+empsalary as varchar) from Employee1_error1
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value » to data type int.
we are adding backslash sign between empid and empsalary and coverting the whole into varchar but why it’s throwing error
The Reason is empid is a int field empsalary is a float field and we are doing a complete conversion of all values to varchar that’s why it is throwing error
In order to fix this error Cast Empid Seperately to varchar and same with Empsalary as varchar than added them to backslash.
select cast(empid as varchar)+»+ cast(empsalary as varchar) as ‘EmpidEmpsalary’ from Employee1_error1
Output
EmpidEmpsalary
15000
26000
38000
49000
510000