Conversion failed when converting the varchar value '0:sval:' to data type int - sql

Conversion failed when converting the varchar value '0:sval:' to data type int.
Please help, I'm getting this error message when looking for data for specific dates in my table.
My query:
SELECT *,
CAST(GETDATE() as DATE) as XTRA_REPORTED_DATE
FROM [RS].[REPORTS].[V_VALIDATOR_DIAGNOSTIC_EVENT_EXPLODED]
WHERE TXN_DATE_TIME BETWEEN '2021-09-28 22:13:36' AND '2021-09-28 22:13:37'
AND IS_OK=0
The function the table is using:
FUNCTION [REPORTS].[godValidatorSplit] (#inputString varchar(max), #isInputHex tinyint)
RETURNS #return TABLE (val varchar(max))
AS
BEGIN
DECLARE #xml xml
SET #xml = CONVERT(xml,'<v>'+
REPLACE(REPLACE(#inputString,',','</v><v>'),char(10),'')
+'</v>')
INSERT INTO #return(val)
SELECT CASE
WHEN (#isInputHex<>0)
THEN
CASE
WHEN (v.value('.','varchar(MAX)') NOT LIKE '%[^a-fA-F0-9]%')
THEN convert(bigint, convert(varbinary, '0x' + RIGHT('00000000'+v.value('.','varchar(MAX)'),8), 1))
ELSE 0
END
ELSE v.value('.','varchar(MAX)')
END
FROM #xml.nodes('/v') as a(v)
RETURN
END

Related

Error converting datatype nvarchar to numeric for empty XML node in case of OPENXML sql

I was getting an error
Error converting datatype nvarchar to numeric
when converting an empty node using OPENXML. I tried different ways of CAST and CONVERT methods but still was getting the same error then end up using the following way.
This is the SQL query:
IF OBJECT_ID('tempdb..#TempData') IS NOT NULL
DROP TABLE #TempData
DECLARE #XML XML
SET #XML = '<ArrayOfTempData>
<TempData>
<StudentId>1418431</StudentId>
<Name>Bill</Name>
<DeptId>2130900</DeptId>
<Fees p3:nil="true" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance" />
</TempData>
<TempData>
<StudentId>1418431</StudentId>
<Name>Samuel</Name>
<DeptId>2280971</DeptId>
<Fees>4628617.156</Fees>
</TempData>
</ArrayOfTempData>'
DECLARE #handle INT
DECLARE #PrepareXmlStatus INT
EXEC #PrepareXmlStatus= sp_xml_preparedocument #handle OUTPUT, #XML
SELECT
StudentId, Name, DeptId, Fees
-- nullif(Fees , '') as Fees,
-- CASE WHEN Fees = '' THEN NULL ELSE CAST(Fees AS NUMERIC(13, 3)) END AS Fees,
-- CASE WHEN ISNUMERIC(Fees) <> 1 THEN NULL ELSE CAST(Fees AS NUMERIC(13, 3)) END AS Fees,
-- CONVERT(NUMERIC(13, 3), NULLIF(Fees, '')) AS Fees
INTO
#TempData
FROM
OPENXML(#handle, '/ArrayOfTempData/TempData', 2)
WITH (StudentId INT,
Name VARCHAR(50),
DeptId INT,
Fees NUMERIC(13, 3) 'Fees[.!=""]'
)
SELECT * FROM #TempData
Commented lines are some other ways I tried then I used the SchemaDeclaration way.
Any better suggestions?
You can use nodes function to read the xml.
SELECT StudentId = n.value('(./StudentId)[1]', 'int'),
NAME = n.value('(./Name)[1]', 'Varchar(8000)'),
DeptId = n.value('(./DeptId)[1]', 'int'),
Fees = n.value('(./Fees)[1]', 'Varchar(8000)')
FROM #xml.nodes('/ArrayOfTempData/TempData') AS a(n)

SQL Server 2014: How to cast a string value to int only if the value can be casted?

I try to cast a string value in a field of a table to int, but only in the case that the value stores a value that can be casted to int (in the other case the original value must be returned). Example:
DECLARE #ErrorCode nvarchar(1024)
SET #ErrorCode = 'a10'
SELECT IIF(TRY_CAST(#ErrorCode AS int) IS NULL, #ErrorCode, CAST(#ErrorCode AS int))
I've seen similar codes on StackOverflow.
My problem is that the SQL Server (2014) does not seem to short-circuit, and executes the cast always, even if TRY_CAST(#ErrorCode AS int) results in NULL. The result of the code above is the error "Conversion failed when converting the nvarchar value 'a10' to data type int."
See this sample on rextester.com
I also tried other variants with the same result:
SELECT CASE WHEN TRY_CAST(#ErrorCode AS int) IS NULL THEN #ErrorCode ELSE (SELECT CAST(#ErrorCode AS int)) END
SELECT CASE TRY_CAST(#ErrorCode AS int) WHEN 1 THEN CAST(#ErrorCode AS int) ELSE #ErrorCode END
How can I achieve my goal (avoid the cast in case the value in #ErrorCode cannot be casted)?
The simple solution would be to use COALSECE:
DECLARE #ErrorCode nvarchar(1024)
SET #ErrorCode = 'a10'
SELECT COALSECE(CAST(TRY_CAST(#ErrorCode AS int) as nvarchar(1024)), #ErrorCode)
However, I don't see the point of casting to int and then back to nvarchar.
To validate NULL you should IS NULL
DECLARE #ErrorCode NVARCHAR(1024)
SET #ErrorCode = 'a10'
SELECT IIF(TRY_CAST(#ErrorCode AS int) IS NULL, #ErrorCode, CAST(CAST(#ErrorCode AS int) AS VARCHAR(50)))
You need to convert the INT again to VARCHAR again to avoid the implicit conversion. IIF returns the data type with the highest precedence from the types in true_value and false_value.
The problem I see is trying to hold 2 different types in a single column. I'm not sure how you plan to use this information, but you could split the values in to numeric and text columns based on the type. You can do an ISNUMERIC() check and CAST to INT if it's true, otherwise leave it as text, like so:
CREATE TABLE #ErrorCodes ( ErrorCode NVARCHAR(10) )
INSERT INTO #ErrorCodes
( ErrorCode )
VALUES ( '123' ),
( 'a10' ),
( 'bbb' ),
( '456' )
SELECT ErrorCode AS OriginalVal ,
CASE WHEN ISNUMERIC(ErrorCode) = 1 THEN CAST(ErrorCode AS INT)
ELSE NULL
END AS NumericVal ,
CASE WHEN ISNUMERIC(ErrorCode) = 0 THEN ErrorCode
ELSE NULL
END AS NonNumericVal
FROM #ErrorCodes
DROP TABLE #ErrorCodes
Produces:
OriginalVal NumericVal NonNumericVal
=====================================
123 123 NULL
a10 NULL a10
bbb NULL bbb
456 456 NULL

SQL convert string data in hexadecimal format into string text

I have a table which has a column X. X will be storing large text values in hex format. Now I want to convert hex to raw and validate the data. But when I am using the below query,
I am getting only some part of text after running the query not the complete text. Actually original text is very large....
select UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW(X)) as a from table name
I also tried the below query, but no use it also extracts the same
decalre #a varchar(max)
select UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW(X)) as new from table name.
Kindly let me know how can i extract or see large text from sql. Sample query may be helpful.
For MS-SQL 2008 the following stored proc will convert a hex string into a varchar(max):
if exists (select * from dbo.sysobjects where name = 'f_hextostr' and xtype = 'FN')
drop function [dbo].[f_hextostr]
GO
CREATE FUNCTION [dbo].[f_hextostr] (#hexstring VARCHAR(max))
RETURNS VARCHAR(max)
AS
begin
declare #char1 char(1), #char2 char(1), #strlen int, #currpos int, #result varchar(max)
set #strlen=len(#hexstring)
set #currpos=1
set #result=''
while #currpos<#strlen
begin
set #char1=substring(#hexstring,#currpos,1)
set #char2=substring(#hexstring,#currpos+1,1)
if (#char1 between '0' and '9' or #char1 between 'A' and 'F')
and (#char2 between '0' and '9' or #char2 between 'A' and 'F')
set #result=#result+
char((ascii(#char1)-case when #char1 between '0' and '9' then 48 else 55 end)*16+
ascii(#char2)-case when #char2 between '0' and '9' then 48 else 55 end)
set #currpos = #currpos+2
end
return #result
end
GO
To use just do something like:
select dbo.f_hextostr('0x3031323')
or
select dbo.f_hextostr(X) from MyTable
This can be done in SQL server using built-in conversions via varbinary data type.
-- VARCHAR TO (HEX) VARCHAR
SELECT CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), 'Help'), 1) -- '0x48656C70'
-- (HEX) VARCHAR TO VARCHAR
SELECT CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), '0x48656c70', 1)) -- 'Help' (requires 0x)
SELECT CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), '48656c70', 2)) -- 'Help' (assumes 0x)
It seems that this works better for me.
if exists (select * from dbo.sysobjects where name = 'HexToStr' and xtype = 'FN')
drop function [dbo].[HexToStr]
GO
CREATE FUNCTION [dbo].[HexToStr] (#hexstring VARCHAR(max))
RETURNS VARCHAR(max)
AS
begin
return #hexstring
end
GO

SQL take just the numeric values from a varchar

Say i have a few fields like the following:
abd738927
jaksm234234
hfk342
ndma0834
jon99322
Type: varchar.
How do I take just the numeric values from this to display:
738927
234234
342
0834
99322
Have tried substring however the data varies in length, and cast didnt work either due to being unable to convert, any ideas?
Here's the example with PATINDEX:
select SUBSTRING(fieldName, PATINDEX('%[0-9]%', fieldName), LEN(fieldName))
This assumes (1) the field WILL have a numeric, (2) the numerics are all grouped together, and (3) the numerics don't have any subsequent characters after them.
Extract only numbers (without using while loop) and check each and every character to see if it is a number and extract it
Declare #s varchar(100),#result varchar(100)
set #s='as4khd0939sdf78'
set #result=''
select
#result=#result+
case when number like '[0-9]' then number else '' end from
(
select substring(#s,number,1) as number from
(
select number from master..spt_values
where type='p' and number between 1 and len(#s)
) as t
) as t
select #result as only_numbers
DECLARE #NonNumeric varchar(1000) = 'RGI000Testing1000'
DECLARE #Index int
SET #Index = 0
while 1=1
begin
set #Index = patindex('%[^0-9]%',#NonNumeric)
if #Index <> 0
begin
SET #NonNumeric = replace(#NonNumeric,substring(#NonNumeric,#Index, 1), '')
end
else
break;
end
select #NonNumeric -- 0001000
Well if you don't want to create a function, you can just something like this:
cast(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(replace(replace(YOUR_COLUMN
,'A',''),'B',''),'C',''),'D',''),'E',''),'F',''),'G',''),'H',''),'I',''),'J','')
,'K',''),'L',''),'M',''),'N',''),'O',''),'P',''),'Q',''),'R',''),'S',''),'T','')
,'U',''),'V',''),'W',''),'X',''),'Y',''),'Z',''),'$',''),',',''),' ','') as float)
I think you're wanting VBA's Val() function. Easy enough to accomplish with IsNumeric()
create function Val
(
#text nvarchar(40)
)
returns float
as begin
-- emulate vba's val() function
declare #result float
declare #tmp varchar(40)
set #tmp = #text
while isnumeric(#tmp) = 0 and len(#tmp)>0 begin
set #tmp=left(#tmp,len(#tmp)-1)
end
set #result = cast(#tmp as float)
return #result
end
select substring(
'jaksm234234',
patindex('%[0-9]%','jaksm234234'),
LEN('jaksm234234')-patindex('%[0-9]%','jaksm234234')+2
)
input table
if you have data like above in the image, then use the below query
select field_3 from table where PATINDEX('%[ ~`!##$%^&*_()=+\|{};",<>/?a-z]%', field_3)=0
Results will be look like this
Result table
Extract only numbers from a string. Returns a string with all the numbers inside. Example: this1is2one345long6789number will return 123456789
CREATE FUNCTION [dbo].[GetOnlyNumbers] (#Temp VARCHAR(1000))
RETURNS VARCHAR (1000) AS BEGIN
DECLARE #KeepValues AS VARCHAR(50)
SET #KeepValues = '%[^0-9]%'
WHILE PATINDEX(#KeepValues, #Temp) > 0
SET #Temp = STUFF(#Temp, PATINDEX(#KeepValues, #Temp), 1, '')
RETURN #Temp
END
A right with patindex for the reverse string works also for those
SELECT [Column],
CAST(RIGHT([Column], PATINDEX('%[0-9][^0-9]%', REVERSE([Column])+' ')) AS INT) as [Num]
FROM (VALUES
('abd738927'),
('jaksm234234'),
('hfk342'),
('ndma0834'),
('jon99322'),
) val([Column])
Column
Num
abd738927
738927
jaksm234234
234234
hfk342
342
ndma0834
834
jon99322
99322

Conversion failed when converting the nvarchar value '20,21' to data type int

SELECT SUM(PayAmount)
FROM TeacherPayment_Detail
WHERE TeacherPaymentId IN (TeacherPayment.Advance_IDs)
i want the sum up of advance taken by a teacher by this query. where Advance_IDs are Id's of recods of advance taken by teacher. but sql giving following error.
Conversion failed when converting the nvarchar value '20,21' to data type int.
note that if Advance_IDs has one value then error not occure this error occure on more then one value
I explored for conversion the nvarchar to int by splitting function but i don't found the functions of my requirements.
this is due to
SELECT SUM(PayAmount)
FROM TeacherPayment_Detail
WHERE TeacherPaymentId IN ('20,21' )
but SQL Server Expects
SELECT SUM(PayAmount)
FROM TeacherPayment_Detail
WHERE TeacherPaymentId IN ('20','21' )
So you can do any one of the following
write some function which will tokenise the '20,21' to '20','21' in
SQL (it is best to do a function which will returns a table)
SELECT SUM(PayAmount)
FROM TeacherPayment_Detail
WHERE TeacherPaymentId IN (select val from Function_Split(TeacherPayment.Advance_IDs )
Pass value in the form 'val1','val2'
When it is only one value it will be 'val' and works, but when it is more than one value, it will 'val1,val2'. so this wont works causing error. It will work if you pass like this 'val1','val2'
** Function **
CREATE FUNCTION GetTokenizeValue
(
#strCSVString VARCHAR(4000)
)
RETURNS
#Result TABLE
(
-- Add the column definitions for the TABLE variable here
ID int
)
AS
BEGIN
; WITH CTE(Start, [Stop]) AS
(
SELECT 1, CHARINDEX(',' , #strCSVString )
UNION ALL
SELECT [Stop] + 1, CHARINDEX(',' ,#strCSVString , [Stop] + 1)
FROM CTE
WHERE [Stop] > 0
)
INSERT INTO #Result
SELECT SUBSTRING(#strCSVString , Start, CASE WHEN stop > 0 THEN [Stop]-Start ELSE 4000 END) AS stringValue
FROM CTE
RETURN
END
your select query will be
SELECT SUM(PayAmount)
FROM TeacherPayment_Detail
WHERE TeacherPaymentId IN (select * from dbo.GetTokenizeValue(TeacherPayment.Advance_IDs))
You can create a split function using the following link:
Convert Comma Separated String to Table Column
Use following user defined function
Create Function dbo.CsvToInt ( #Array varchar(1000))
returns #IntTable table (IntValue int) AS
begin
declare #separator char(1)
set #separator = ','
declare #separator_position
int declare #array_value varchar(1000)
set #array = #array + ','
while patindex('%,%' , #array) <> 0
begin
select #separator_position = patindex('%,%' , #array)
select #array_value = left(#array, #separator_position - 1)
Insert #IntTable Values (Cast(#array_value as int))
select #array = stuff(#array, 1, #separator_position, '')
end
return end
Use as below
Select * from dbo.CsvToInt('1,5,11')
In your case
SELECT SUM(PayAmount)
FROM TeacherPayment_Detail
WHERE TeacherPaymentId IN (Select * from dbo.CsvToInt(TeacherPayment.Advance_IDs))