T-SQL, XQuery Invalid Column - sql-server

I'm just learning XQUERY and trying to accomplish what I thought would be very simple. Here's my T-SQL code:
DECLARE #XML xml
set #xml = '<resultsets><AppVersion>13.0</AppVersion></resultsets>'
-- Code below is wrong
select
ResultSets.AppVersion.query('AppVersion').value('.', 'varchar(100)') as AppVersion
from #XML.nodes('/resultsets/AppVersion') ResultSets(AppVersion)
I cannot figure out exactly how to query that inner element, appversion. I'm not getting any errors, but I'm unable to return that 13.0 within the appversion inner-element. Can someone please help?

You've got one AppVersion too many. This returns your 13.0 :
DECLARE #XML xml
set #xml = '<resultsets><AppVersion>13.0</AppVersion></resultsets>'
-- Code below is right
select
ResultSets.AppVersion.value('.', 'varchar(100)') as AppVersion
from #XML.nodes('/resultsets/AppVersion') ResultSets(AppVersion)
Your nodes method already gets down to the AppVersion nodes, so from there you don't need a further query, just the value.

If you only want one row as a result there is no need to use nodes.
DECLARE #XML xml
set #xml = '<resultsets><AppVersion>13.0</AppVersion></resultsets>'
select #XML.value('(/resultsets/AppVersion)[1]', 'varchar(100)') as AppVersion

Related

Read Xml Field From Image field Sql Server

I am trying to change the code below and read it from the image field
DECLARE #xml XML
SELECT #xml= x FROM OPENROWSET (BULK ''' + #XMLFILE + ''', SINGLE_BLOB) AS T(x)
How Can I Convert To Xml Type?
SELECT #xml= FileField FROM FileListTable (FileField is İmage Field)
Try:
SELECT #xml = CAST(CAST(FileField AS VARBINARY(MAX)) AS XML)
FROM FileListTable
Whether this works or not, may depend on how the XML was converted to the IMAGE data type before being inserted into your table. This db<>fiddle exercises various ways of inserting XML into an IMAGE column and several ways (both good and bad) to try to get it out. Almost surprisingly, the cast to VARBINARY(MAX) and then to XML seems to handle the cases demonstrated.

Remove Escaped character from XML in SQL Server

How can the & be shown inside the XML field?
DECLARE #xml XML
SET #xml = (SELECT 'test&test' AS xml_entity
FOR XML PATH('xml_merge'),TYPE)
SELECT #xml
The result is showing a &
<xml_merge> <xml_entity>test&test</xml_entity> </xml_merge>
I also tried with CDATA tag but that didn't solve it:
DECLARE #xml XML
SET #xml = (SELECT '<![CDATA[test&test]]>' AS xml_entity
FOR XML PATH('xml_merge'),TYPE)
SELECT #xml
<xml_merge>
<xml_entity><![CDATA[test&test]]></xml_entity>
</xml_merge>
How to handle this? I need to show the & instead of &
Expected result
<xml_merge> <xml_entity>test&test</xml_entity> </xml_merge>
Ampersand is a special character in XML. That's why it requires its entity &
Please try the following SQL. It will show you that after the SELECT ... as a VARCHAR(), the entity is gone. It remains as such just inside the XML data type.
You can check it here: 2.4 Character Data and Markup
SQL
DECLARE #xml XML;
SET #xml = (SELECT 'test & test' AS xml_entity
FOR XML PATH('xml_merge'),TYPE);
SELECT #xml;
SELECT #xml.value('(/xml_merge/xml_entity/text())[1]','VARCHAR(100)') AS xml_entity;
Output
xml_entity
test & test
This seems like an X/Y problem. You want invalid XML to be returned as XML. If you want the string value then you can pull it from the XML as a value and the escape characters will be removed, however, if you want invalid XML the way you outlined it above then you will have to convert the XML to a string and then replace the escapes.
DECLARE #xml XML
SET #xml = (SELECT 'test&test' AS xml_entity
FOR XML PATH('xml_merge'),TYPE)
SELECT #xml
DECLARE #XmlBlob NVARCHAR(MAX)=CAST(#Xml AS NVARCHAR(MAX))
SELECT REPLACE(#XmlBlob,'&','&')
<xml_merge><xml_entity>test&test</xml_entity></xml_merge>

The label 'T14' has already been declared. Label names must be unique within a query batch or stored procedure

enter image description hereIncorrect syntax near '<'.
The label 'T14' has already been declared. Label names must be unique within a query batch or stored procedure.
The code follows:
DECLARE #XML AS XML
SELECT #XML = XMLData
FROM ReadXmlFile
WHERE IndexRow = #IndexRow;
Declare #Str Varchar(max)
SET #Str=(select cast(#XML as varchar(max)))
EXEC(#Str)
PRINT(#Str)
table ReadXmlFile is contains 3 column (IndexRow,XmlData,DateTime) that value of XmlData is filled by the user uploaded file
and #Str in Old StoredProcedure was:
Declare #Str Varchar(1000)
SET #Str='BULK INSERT #tbltest1
FROM ''//192.168.1.20/Softwares/' + #stfName + '/Reading/' + #FILE_NAME + '''
WITH
(
DATAFILETYPE =''char'',
Rowterminator=''\n''
--firstrow=10
)'
now i want #tbltest1 in part **SET #Str='BULK INSERT #tbltest1** fill by column XmlData from table ReadXmlFile Instead Fill by the following path '//192.168.1.20/Softwares/' + #stfName + '/Reading/' + #FILE_NAME +
this is part of the file XML:
<TestUniverseExport xmlns="http://www.omicron.at/dataexport">
<TM_Common>
<TestReportID>c522187c-2175-4b84-90b3-ebb6f854694c</TestReportID>
<TestReportOrder>1</TestReportOrder>
<Name>OMICRON Advanced Distance</Name>
<Version>2.40 </Version>
<Title>REL521-DE805.adt</Title>
<TestStartDate>1394-08-03T14:00:20+04:30</TestStartDate>
<TestEndDate>1394-08-03T14:02:45+04:30</TestEndDate>
<Offline>false</Offline>
<Overload>false</Overload>
<HWCReportOrder>0</HWCReportOrder>
<TOReportOrder>0</TOReportOrder>
<Assessment>PASSED</Assessment>
<ManualAssessment>false</ManualAssessment>
<PartiallyExecuted>false</PartiallyExecuted>
<Error>false</Error>
<TestStartMode>IMMEDIATELY</TestStartMode>
</TM_Common>
<TM_Dist>
<TestReportID>c522187c-2175-4b84-90b3-ebb6f854694c</TestReportID>
<TestReportOrder>1</TestReportOrder>
<TestModel>CONSTANT_CURRENT</TestModel>
What you show us, is not enough to answer your question properly. I must admit, I do not even see a question... And I doubt, that the message you get is really connected to this T14 within your dateTimes...
Your XML is - after adding some closing tags - perfectly okay:
DECLARE #xml XML=
N'<TestUniverseExport>
<TM_Common>
<TestReportID>c522187c-2175-4b84-90b3-ebb6f854694c</TestReportID>
<TestReportOrder>1</TestReportOrder>
<Name>OMICRON Advanced Distance</Name>
<Version>2.40 </Version>
<Title>REL521-DE805.adt</Title>
<TestStartDate>1394-08-03T14:00:20+04:30</TestStartDate>
<TestEndDate>1394-08-03T14:02:45+04:30</TestEndDate>
</TM_Common>
</TestUniverseExport>';
SELECT elmnts.value('local-name(.)','nvarchar(max)') AS ElementName
,elmnts.value('text()[1]','nvarchar(max)') AS ElementValue
FROM #xml.nodes('/TestUniverseExport/TM_Common/*') A(elmnts);
There must be something within the data, which brings up this error. Is XMLData a natively typed XML column?
And it is totally unclear what you are trying to get here:
Declare #Str Varchar(max)
SET #Str=(select cast(#XML as varchar(max)))
EXEC(#Str)
This is rather weird... Casting a XML to a string type will not result in an executable SQL-command...
Please try to add to your question and - if possible - provide a MCVE, to reproduce your issue.
UPDATE: After you edited your quesiton...
From the screenshot I take, that the table contains XML-typed values. And you try to change the old code in a way, that the XML is not taken from a file any more but directly out of that table. Correct so far?
If my assumptions are correct, this might be really trivial:
DECLARE #XML AS XML;
SELECT #XML = XMLData
FROM ReadXmlFile
WHERE IndexRow = #IndexRow;
Declare #Str Varchar(max);
SET #Str=cast(#XML as varchar(max));
The old code needed the dynamically created statement (together with EXEC() and PRINT) to load the XML from the file system. But now you have the XML directly in your table. So just take it, cast it and proceed from there...
What your own attempts did, was to execute something which was not a SQL-Command by any means...
You are executing an invalid sql query. See on how to use sql exec | execute
Wrap your query with the correct strings.
DECLARE #XML AS XML
SELECT #XML = XMLData
FROM ReadXmlFile
WHERE IndexRow = #IndexRow;
Declare #Str Varchar(max)
SET #Str='select '''+cast(#XML as varchar(max))+''''
EXEC(#Str)
PRINT(#Str)
or if you want to view it as xml.
SET #Str='select cast('''+cast(#XML as varchar(max))+''' as xml)'

Xquery delete with Xpath from sql:variable

I am having Xpath to delete from XML in an VARCHAR(MAX) variable, but XML.modify('delete '+#MyXpath) give an error ,
The argument 1 of the XML data type method "modify" must be a string
literal.
DECLARE #myXML XML,
#MyXpath VARCHAR(MAX)
-- Processing of Xpaths for components needed to remove
-- Adding those in #XpathsToRemove
SELECT TOP(1) #MyXpath = [XPATH]
FROM #XpathsToRemove
SET #myXML.modify('delete '+#MyXpath)
Is there any way to remove those components with Xpath available in #MyXpath variable ?
-- Edit Example XML
DECLARE #myXML XML ='<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Dont forget me this weekend!</body>
</note>'
,#MyXpath VARCHAR(MAX) = '//note/from'
-- There are many Xpaths and dynamically generated with some processing so I don't want to hardcode Xpath there
SET #myXML.modify('delete '+#MyXpath)
--This doesn't works too
-- SET #myXML.modify('delete "sql:variable("MyXPath")"')
SELECT #myXML
Thanks guys, I got solution by EXEC to generate dynamic queries.
Following is link that solved my issue,
How to using for loop using XQuery to delete xml nodes [duplicate]
Solution,
DECLARE #str nvarchar(MAX)
SET #str = 'SET #MyXML.modify('+char(39)+'delete '+#MyXPath+'/*'+char(39)+'); '
EXEC sp_executesql #str, N'#MyXML xml output', #MyXML output

Add node to XML using TRANSACT-SQL

I've been struggling with this simple piece of code without result. I'm just trying to add a new node to an XML variable.
DECLARE #XML XML;
SET #XML = '<root>
<policyData>
<txtComentario />
<idRegProducto>76</idRegProducto>
<txtDuracion>24</txtDuracion>
</policyData>
</root>';
DECLARE #NODE XML;
SET #NODE = '<newNode>10</newNode>';
SET #XML.modify
('insert sql:variable("#NODE") as first
into (/root/policyData)[0]')
SELECT #XML;
There is no errors, but the new node is not showing in the output. Is there something that I must setup first before using XML in SQL Server? Any suggestion why this is not working?
Thanks in advance!
When you use [0] you are actually saying [position()=0]. The first node has position 1 so you should change the predicate to [1] if you want to insert the new node into the first occurrence of policyData.

Resources