XML Conversion issue - sql

Getting the following error; "Error converting data type varchar to numeric".
This happens when trying to select data from an XML input. Below is the code:
DECLARE #XmlIn XML = '<rec>
<targetId>10</targetId>
<categoryId>4</categoryId>
<percent>2</percent>
<AgreementDurationMin></AgreementDurationMin>
<AgreementDurationMax></AgreementDurationMax>
</rec>'
INSERT INTO WizzTable
( CommissionTargetId ,
CommissionPercentageCategoryId ,
Percentage ,
AgreementDurationMin ,
AgreementDurationMax
)
SELECT targetId = NULLIF(cb.n.value('(targetId)[1]', 'INT'),
'') ,
categoryId = NULLIF(cb.n.value('(categoryId)[1]',
'SMALLINT'), '') ,
percentage = NULLIF(cb.n.value('(percent)[1]',
'DECIMAL(17,2)'), '') ,
AgreementDurationMin = ISNULL(NULLIF(cb.n.value('(AgreementDurationMin)[1]',
'INT'), ''), 0) ,
AgreementDurationMax = NULLIF(cb.n.value('(AgreementDurationMax)[1]',
'INT'), '')
FROM #XmlIn.nodes('rec') cb ( n )
WHERE cb.n.value('(percent/text())[1]', 'INT') > 0
Any ideas? Thanks!

What percent element type? you try to convert it to DECIMAL(17,2) in your select; but in your where clause, it is INT.
The error complains your Nullif default value. Sql cannot convert a '' to a decimal.
Fix:
DECLARE #XmlIn XML = '<rec>
<targetId>10</targetId>
<categoryId>4</categoryId>
<percent>2</percent>
<AgreementDurationMin></AgreementDurationMin>
<AgreementDurationMax></AgreementDurationMax>
</rec>'
INSERT INTO WizzTable
( CommissionTargetId ,
CommissionPercentageCategoryId ,
Percentage ,
AgreementDurationMin ,
AgreementDurationMax
)
SELECT targetId = NULLIF(cb.n.value('(targetId)[1]', 'INT'),
'') ,
categoryId = NULLIF(cb.n.value('(categoryId)[1]',
'SMALLINT'), '') ,
percentage = NULLIF(cb.n.value('(percent)[1]',
'DECIMAL(17,2)'), '0') ,
AgreementDurationMin = ISNULL(NULLIF(cb.n.value('(AgreementDurationMin)[1]',
'INT'), ''), 0) ,
AgreementDurationMax = NULLIF(cb.n.value('(AgreementDurationMax)[1]',
'INT'), '')
FROM #XmlIn.nodes('rec') cb ( n )
WHERE cb.n.value('(percent/text())[1]', 'DECIMAL(17,2)') > 0

You are setting the empty string here
... = NULLIF(something,'')
The empty string is not valid in an numeric context. The types must be the same for expression1 and expression2: https://msdn.microsoft.com/en-us/library/ms177562.aspx
Try it like this:
SELECT targetId = NULLIF(cb.n.value('(targetId)[1]', 'INT'),
0) ,
categoryId = NULLIF(cb.n.value('(categoryId)[1]',
'SMALLINT'), 0) ,
percentage = NULLIF(cb.n.value('(percent)[1]',
'DECIMAL(17,2)'), 0) ,
AgreementDurationMin = ISNULL(NULLIF(cb.n.value('(AgreementDurationMin)[1]',
'INT'), 0), 0) ,
AgreementDurationMax = NULLIF(cb.n.value('(AgreementDurationMax)[1]',
'INT'), 0)
FROM #XmlIn.nodes('rec') cb ( n )
WHERE cb.n.value('(percent/text())[1]', 'INT') > 0

Related

Two multi-value parameters in SSRS

I have two multi-value parameters in my SQL: where (PayToTIN IN (#PayToTIN) or PCP_ProvId IN (#PCP_ProvId). I am trying to drop in multiple values in either or parameters however when I drop in a value in either parameter, SSRS treats the other parameter as ''. I am also unable to null out the either param because they are multi-value. Is there a workaround to run multiple values in either one or the other parameter?
Declare #PayToTIN as varchar(max) = '562660402' --'562660402'
Declare #PCP_ProvId as varchar(max) --= 'LASRL12550' --'LASRL12550'
declare #detailfields as varchar(max) = NULL
declare #PayToTIN_switch varchar(max) =
( select max(PayToTIN)
from LA_Temp.dbo.vMemberPCP
where cast(PayToTIN as varchar) in (#PayToTIN)
)
declare #PCPAssignmentID_switch varchar(max) =
( select max(PCP_ProvId)
from LA_Temp.dbo.vMemberPCP
where cast(PCP_ProvId as varchar) in (#PCP_ProvId)
)
declare #include_PayToTIN bit = case when 'Pay To Tin' in (#detailfields) then 1 else 0 end
declare #include_PCP_ProvId bit = case when 'PCP ProvID' in (#detailfields) then 1 else 0 end
select distinct
x.CarrierMemID
-- , MemberName
, MbrLastName =rtrim( e.LastName)
, MbrFirstName = rtrim(e.FirstName)
, MbrMI = rtrim(e.MiddleName)
, x.DOB
, x.Age
, x.Sex
, Address = e.addr1
, City = e.city
, State = e.state
, Zip = e.zip
, Parish = e.county
, MemPhone = e.phone
, PCPName
, PCP_NPI
, PCPProvID
, PCPEffDate
, Specialty
, ServiceLocation
, PayToProvider
, PayToTIN
, PayToProvID
, PCP_ProvId
, PCPAssignment
from LA_Temp.dbo.vMemberPCP x
inner join PlanReport_QNXT_LA.dbo.enrollkeys ek
on x.enrollid = ek.enrollid
inner join PlanReport_QNXT_LA.dbo.orgpolicy o
on o.orgpolicyid = ek.orgpolicyid
and right(rtrim(o.policynum),2) <> 'BH'
inner join PlanReport_QNXT_LA.dbo.member m
on ek.memid = m.memid
inner join PlanReport_QNXT_LA.dbo.entity e
on e.entid = m.entityid
--where PayToTIN = #PayToTIN --AMB 05/07/18
where (PayToTIN IN (#PayToTIN)
or '' = #PayToTIN_switch
)
or ( PCP_ProvId IN (#PCP_ProvId)
or '' = #PCPAssignmentID_switch
)
where (case when PayToTIN = '' then null else PayToTIN end in (#PayToTIN))
OR (case when PCP_ProvId = '' then null else PCP_ProvId end in (#PCP_ProvId))

How to store semicolon separated long string into multiple columns?

Basically due to restriction on live server, I cannot use text file so I need to hard code the data in T-SQL code.
So first I created string from text file like this:
("001122;Sale Item 1", "001123;Sale Item 23", "001124;Sale Item 24", .... )
I have this table structure:
DECLARE #Product TABLE(ProductCode INT NOT NULL, Description nvarchar(100) NOT NULL)
First I need to store code and description in a table variable. Once that's done, then I can easily map it to the physical table and update the records.
How can I achieve this something similar to:
insert into #Product(ProductCode, Description)
values ("001122;Sale Item 1", "001123;Sale Item 23", "001124;Sale Item 24", .... )
Code Description
001122 Sale Item1
001123 Sale Item2
001124 Sale Item3
If you have fixed format like in example then you can achieve desired output simply using CHARINDEX and SUBSTRING
SELECT
SUBSTRING(description, 0, CHARINDEX(';', DESCRIPTION, 0)) code,
SUBSTRING(description, CHARINDEX(';', DESCRIPTION, 0)+1, LEN(DESCRIPTION)) Description
FROM #Product
OUTPUT:
code Description
------------------------
001122 Sale Item 1
001123 Sale Item 23
001124 Sale Item 24
I crated a sample for you, please check this
declare #Questions varchar(100)= '"001122;Sale Item 1", "001123;Sale Item 23", "001124;Sale Item 24"'
DECLARE #myXML AS XML = N'<H><r>' +Replace(#Questions, ',', '</r><r>') + '</r></H>'
select #myXML
;WITH cte
AS (
SELECT CAST(N'<H><r>' + Replace(Vals.id.value('.', 'NVARCHAR(50)') ,';' , '</r><r>') + '</r></H>' as XML) AS val
FROM #myXML.nodes('/H/r') AS Vals(id)
)
,mycte1 as (
SELECT distinct
Replace( S.a.value('(/H/r)[1]', 'NVARCHAR(50)') , '"', '') AS c1,
Replace( S.a.value('(/H/r)[2]', 'NVARCHAR(50)') , '"', '') AS c2
FROM cte CROSS APPLY val.nodes('/H/r') S(a)
)
select * from mycte1
The output will be
c1 c2
001123 Sale Item 23
001124 Sale Item 24
001122 Sale Item 1
Here we go matey:
DECLARE #MyString nvarchar(max) = '"001122;Sale Item 1", "001123;Sale Item 23", "001124;Sale Item 24"';
DECLARE #delimiter1 nvarchar(1)
, #delimiter2 nvarchar(1)
, #Start1 int
, #End1 int
, #Length int
, #cNEXTVALUE nvarchar(1000)
, #cNEXTVALUE2 nvarchar(1000)
, #StringLength int;
DECLARE #Product TABLE (
ProductCode int NOT NULL
, Description nvarchar(100) NOT NULL );
SET #MyString = RTRIM(LTRIM(#MyString));
SET #MyString = REPLACE(#MyString, CHAR(13), '');
SET #MyString = REPLACE(#MyString, CHAR(10), '');
SET #delimiter1 = ';';
SET #delimiter2 = ',';
SET #MyString = REPLACE(#MyString, '"', '')+#delimiter2;
SET #StringLength = LEN(#MyString);
SELECT #Start1 = 0
, #End1 = CHARINDEX(#delimiter1, #MyString, 1);
SELECT #Length = #End1 - #Start1;
WHILE #Length > 0
BEGIN
SET #cNEXTVALUE = SUBSTRING(#MyString, #Start1, #Length);
SET #Start1 = #End1 + 1;
SET #End1 = CHARINDEX(#delimiter2, #MyString, #Start1);
SELECT #Length = #End1 - #Start1;
SET #cNEXTVALUE2 = SUBSTRING(#MyString, #Start1, #Length);
IF LEN(RTRIM(LTRIM(#cNEXTVALUE))) > 0
BEGIN
INSERT INTO #Product
( ProductCode
, Description
)
VALUES
( #cNEXTVALUE, #cNEXTVALUE2 );
END;
SET #Start1 = #End1 + 2;
SET #End1 = CHARINDEX(#delimiter1, #MyString, #Start1);
SELECT #Length = #End1 - #Start1;
END;
SELECT *
FROM #Product;

Give an Explanation for this SQL error "Conversion of a varchar data type to a datetime data type Which resulted in an out-of-range value"

ALTER PROCEDURE [dbo].[TRN_Hold_GetData]
#XMLSearch XML = '<DocumentElement><TRN_Hold_GetData_Custom><HoldId>0</HoldId><FromDate>17-3-2017</FromDate><ToDate>17-2-2017</ToDate></TRN_Hold_GetData_Custom></DocumentElement>'
AS
BEGIN
DECLARE #HoldId INT = 0,
#HoldNo VARCHAR(50) = '',
#Party VARCHAR(100) = '',
#StoneNo VARCHAR(50) = '',
#FromDate VARCHAR(50) = '',
#ToDate VARCHAR(50) = '',
#HoldStatus VARCHAR(20) = '',
#FilterQry NVARCHAR(MAX) = '',
#FinalQry NVARCHAR(MAX) = ''
SELECT
#HoldNo = doc.col.value('HoldNo[1]', 'VARCHAR(50)'),
#Party = doc.col.value('Party[1]', 'VARCHAR(MAX)'),
#StoneNo = doc.col.value('StoneNo[1]', 'VARCHAR(MAX)'),
#FromDate = doc.col.value('FromDate[1]', 'VARCHAR(11)'),
#ToDate = doc.col.value('ToDate[1]', 'VARCHAR(11)'),
#HoldStatus = doc.col.value('HoldStatus[1]', 'VARCHAR(20)')
FROM
#XMLSearch.nodes('/DocumentElement/TRN_Hold_GetData_Custom') doc(col)
SELECT
convert(varchar(11), cast(OnHoldDate as datetime), 103),
ISNULL(TH.HoldId, '') AS HoldId,
ISNULL(TH.HoldNo, '') AS HoldNo,
ISNULL(TH.PartyId, '') AS PartyId,
ISNULL(MP.Party, '') AS Party,
ISNULL(TH.OnHoldDate, '') AS HoldDate,
ISNULL(TH.ExpReleaseDays, '') AS ExpReleaseDays,
ISNULL(TH.ExpReleaseDate, '') AS ExpReleaseDate,
ISNULL(TH.TotalPkt, '') AS TotalPkt,
ISNULL(TH.TotalCts, '') AS TotalCts,
HOLDSTONE, RELEASESTONE,
ISNULL(TH.TotalAmount, '') AS TotalAmount,
ISNULL(TH.HoldById, '') AS HoldById,
ISNULL(TH.Remark, '') AS Remark,
ISNULL(MEmp.firstname, '') + ' ' + ISNULL(MEmp.middlename, '') + ' ' + ISNULL(MEmp.lastname, '') AS HoldUser,
ISNULL(MEmp.firstname, '') + ' ' + ISNULL(MEmp.middlename, '') + ' ' + ISNULL(MEmp.lastname, '') AS UnHoldUser
FROM
dbo.TRN_Hold TH WITH ( NOLOCK )
INNER JOIN
( SELECT SUM(CASE WHEN HoldStatus = 0 THEN 1
ELSE 0
END) AS HOLDSTONE, SUM(CASE WHEN HoldStatus = 1 THEN 1
ELSE 0
END) AS RELEASESTONE, HoldId
FROM TRN_Hold_Detail
GROUP BY HoldId ) AS THD ON TH.HoldId = THD.HoldId
INNER JOIN TRN_Hold_Detail AS HDD WITH ( NOLOCK ) ON HDD.HoldId = THD.HoldId
INNER JOIN mst_Stone AS MS WITH ( NOLOCK ) ON HDD.StoneId = MS.Stone_id
LEFT JOIN MST_Party MP ON TH.PartyId = MP.party_id
LEFT JOIN MST_Employee MEmp ON TH.HoldById = MEmp.employee_id
WHERE HoldNo = (
CASE WHEN #HoldNo = '' or #HoldNo is null THEN HoldNo ELSE #HoldNo END ) AND
convert(varchar(11),cast(OnHoldDate as datetime),101)
between
CASE WHEN #FromDate= ''
THEN OnHoldDate
ELSE convert(varchar(11),#FromDate,101)
END
AND
CASE WHEN #ToDate = ''
THEN OnHoldDate
ELSE convert(varchar(11),#ToDate,101)
END
print #FromDate
print #ToDate
--????????????????????????????????????????????????????????????????
--AND ( CASE WHEN convert(varchar(50),cast(#FromDate as datetime),103)= ''
-- THEN convert(varchar(50),cast(#FromDate as datetime),103)
-- ELSE OnHoldDate
-- END ) >= convert(varchar(50),cast(#FromDate as datetime),103)
--AND ( CASE WHEN convert(varchar(50),cast(#ToDate as datetime),103) = ''
-- THEN convert(varchar(50),cast(#ToDate as datetime),103)
-- ELSE OnHoldDate
-- END ) <= convert(varchar(50),cast(#ToDate as datetime),103)
--????????????????????????????????????????????????????????????????
--AND ( #StoneNo = '' OR ms.Stone_no = #stoneNo )
-- --realse
--AND ((#HoldStatus = 'RELEASE' AND ISNULL(THD.HOLDSTONE, 0) = 0 AND ISNULL(THD.RELEASESTONE, 0) <> 0)
-- --Hold
--OR ( #HoldStatus = 'HOLD' AND ISNULL(THD.HOLDSTONE, 0) <> 0 AND ISNULL(THD.RELEASESTONE, 0) = 0)
-- --Partial
--OR (#HoldStatus = 'PARTIAL' AND ISNULL(THD.HOLDSTONE, 0) <> 0 AND ISNULL(THD.RELEASESTONE, 0) <> 0 )
--OR #HoldStatus = 'ALL'
-- )
-- print #FromDate
-- print convert(nvarchar(20), #FromDate ,106)
--print convert(nvarchar(20), #ToDate ,103)
--OnHoldDate between (case when #FromDate ='' then OnHoldDate else #FromDate end)
--and (case when #ToDate = '' then OnHoldDate else #ToDate end)
END
This is my stored proedure; when I execute it, I get the following error
Msg 242, Level 16, State 3, Procedure TRN_Hold_GetData, Line 45
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value
The DateTime in the XML "17-3-2017" can be interpreted in two different ways - one of which 3rd day of 17th month, is not valid. Make sure you use explicit date formats in your XML in line with XML standards (YYYY-MM-DDThh:mm:ss)
You really should have datetime strings in a universal format, as suggested by Phillip. However, if you do not have control this should properly handle your convert pattern:
declare #dAsStr varchar(max) = '17-3-2017'
select convert(datetime, #dAsStr, 105)

i can't make hibernate sql query

hi i am a noob programmer.
I am learning Hibernate now. And I am frustrated by
SELECT COUNT(*) FROM zipcode a
WHERE (ISNULL( :sido , '') = '' OR a.sido = :sido) AND
(ISNULL( :sigungu , '') = '' OR a.sigungu = :sigungu) AND
(ISNULL( :eupmyun , '') = '' OR a.eupmyun = :eupmyun) AND
(ISNULL( :roadName , '') = '' OR a.road_name = :roadName) AND
(ISNULL( :ri , '') = '' OR a.ri = :ri)
I can't make this sql query to hibernate....
Number num = (Number) session()
.createQuery(
"SELECT COUNT(*) FROM ZipCode a WHERE (ISNULL( :sido , '') = '' OR a.sido = :sido) AND (ISNULL( :sigungu , '') = '' OR a.sigungu = :sigungu) AND (ISNULL( :eupmyun , '') = '' OR a.eupmyun = :eupmyun) AND(ISNULL( :roadName , '') = '' OR a.roadName = :roadName) AND(ISNULL( :ri , '') = '' OR a.ri = :ri) ")
.setParameter("sido", sido).setParameter("sigungu", sigungu).setParameter("eupmyun", eupmyun).setParameter("roadName", roadName).setParameter("ri", ri)
.list();
I try this sql...
I am using Postgresql 9.4 and hibernate 5.0.*
Please help me
1) Instead of createQuery use createSQLQuery as below:
Query query = session.createSQLQuery("SELECT COUNT(*) FROM zipcode a
WHERE (ISNULL( :sido , '') = '' OR a.sido = :sido) AND
(ISNULL( :sigungu , '') = '' OR a.sigungu = :sigungu) AND
(ISNULL( :eupmyun , '') = '' OR a.eupmyun = :eupmyun) AND
(ISNULL( :roadName , '') = '' OR a.road_name = :roadName) AND
(ISNULL( :ri , '') = '' OR a.ri = :ri) ");
Number number =(Number)query.list().get(0);
createQuery - is a HQL query whereas createSQLQuery is a native db query.
Note: make sure the query is in one line else you need to add ('+') concat operator.

How to extract dates from a varchar string

How to extract dates from a varchar string;
Format of data:
Rates from 16th April 2011 to 31st Aug 2011
I want output as '16/04/2011' and '31/08/2011'
Regards,
Nitin
To do not play with day end part like "d","st" etc, it is better to split your string into words and then analyse it. Double spaces being removed at the beginning.
DECLARE #s NVARCHAR(MAX)= 'Rates from 16th April 2011 to 2st Aug 2011'
SET #s = REPLACE(#s, ' ', ' ')
DECLARE #BegDay VARCHAR(2)= '' ,
#begMonth NVARCHAR(100) ,
#BegYear VARCHAR(4)
DECLARE #EndDay VARCHAR(2) ,
#EndMonth NVARCHAR(100) ,
#EndYear VARCHAR(4)
DECLARE #BegDate DATETIME ,
#EndDate DATETIME
DECLARE #Words TABLE
(
Word NVARCHAR(1000) ,
WordNr INT
) ;
WITH c ( Char, Pos, WordNr )
AS ( SELECT SUBSTRING(#s, 1, 1) CHAR ,
1 ,
CAST(0 AS BIGINT)
UNION ALL
SELECT SUBSTRING(#s, pos + 1, 1) CHAR ,
pos + 1 ,
CASE WHEN SUBSTRING(#s, pos + 1, 1) = SPACE(1)
THEN c.WordNr + 1
ELSE c.WordNr
END
FROM c
WHERE pos < LEN(#s)
)
INSERT INTO #Words
( Word ,
WordNr
)
SELECT RTRIM(LTRIM(SUBSTRING(#s, c.Pos,
ISNULL(c2.Pos, LEN(#s)) - c.Pos + 1))) ,
c.WordNr + 1
FROM ( SELECT *
FROM c
) c
LEFT OUTER JOIN C C2 ON c2.WordNr = c.WordNr + 1
AND c2.Char = ' '
WHERE c.char = ' '
OR c.Pos = 1 ;
WITH c ( Word, [CHAR], Pos )
AS ( SELECT T.Word ,
CAST(SUBSTRING(T.Word, 1, 1) AS NVARCHAR(100)) ,
1
FROM #Words T
WHERE WordNr = 3
UNION ALL
SELECT c.Word ,
CAST(SUBSTRING(c.Word, 1, pos + 1) AS NVARCHAR(100)) ,
pos + 1
FROM c
WHERE ISNUMERIC(SUBSTRING(C.Word, c.pos + 1, 1)) = 1
)
SELECT TOP 1
#BegDay = char
FROM c
ORDER BY pos DESC
SET #begMonth = ( SELECT T.Word
FROM #Words T
WHERE T.WordNr = 4
)
SET #BegYear = ( SELECT T.Word
FROM #Words T
WHERE T.WordNr = 5
)
SET #BegDate = #BegDay + '' + #begMonth + #Begyear ;
WITH c ( Word, [CHAR], Pos )
AS ( SELECT T.Word ,
CAST(SUBSTRING(T.Word, 1, 1) AS NVARCHAR(100)) ,
1
FROM #Words T
WHERE WordNr = 7
UNION ALL
SELECT c.Word ,
CAST(SUBSTRING(c.Word, 1, pos + 1) AS NVARCHAR(100)) ,
pos + 1
FROM c
WHERE ISNUMERIC(SUBSTRING(C.Word, c.pos + 1, 1)) = 1
)
SELECT TOP 1
#EndDay = char
FROM c
ORDER BY pos DESC
SET #EndMonth = ( SELECT T.Word
FROM #Words T
WHERE T.WordNr = 8
)
SET #EndYear = ( SELECT T.Word
FROM #Words T
WHERE T.WordNr = 9
)
SET #EndDate = #EndDay + '' + #EndMonth + #Endyear
SELECT #BegDate Begindate ,
#EndDate EndDate