I need to export XML data from a Sql Server table using a known schema.
The schema takes the form
<myField>value</myField>
As far as I can make out I need to use the FOR XML clause in the select statement.
All options for that clause seem to generate XML in the form of:
<element myField=value /element>
i.e. Data is inserted as attributes of elements instead of being values of elements.
It seems that the best way to deal with this need is to handle the XML file generation inside of an application.
Am I correct in this conclusion or is it lack of understanding of TSQL xml capabilities on my part?
thanks
Bob
I don't know if you can get the exact format you are looking for but this comes pretty close. The Point and DateTimeFormat column will be repeated for each row.
SELECT Point
,DateTimeFormat
,DT AS "S/DT"
,V AS "S/V"
,Q AS "S/Q"
FROM mytable
FOR XML PATH(''), TYPE, ELEMENTS, ROOT('Data')
Check out the SQL Fiddle
Related
I need to generate XML document based on a SQL Server table. This is very simple to do with the following syntax.
SELECT *
FROM MyTableName
WHERE name = 'Bob'
FOR XML PATH
What I'm struggling with is figuring out a way to include data types for all elements automatically without having to modify XML and including additional tags manually.
I want XML attributes reflect datatypes found in table definition.
I found the answer through use of SQL Prompt auto complete feature. After typing FOR XML RAW, I explored other options that can be used with it.
As the result I found following two options that can be used with FOR XML RAW
FOR XML RAW, XMLDATA
FOR XML RAW, XMLSCHEMA
I ran the query with those options and looked at the xml document generated by the output. After I realized that this is what I been looking for, I was able to find documentation https://msdn.microsoft.com/en-us/library/bb510461.aspx that explained both options and how it can be used.
I slightly modified my original query,
SELECT *
FROM MyTableName
WHERE 1 = 0
FOR XML RAW, ELEMENTS, XMLSCHEMA
By including 1=0 in where clause allowed me to only generate attribute without any data. Now all I had to do was to copy output into notepad++ and save it as .xsd file.
I have written an interface to interact with the CubeIQ BlackBox (www.magiclogic.com) and I have an SQL Server 2005 database table where I store some regular text fields, dates, and two pieces of XML in columns that have an XML data type.
There are a few values I want to pick out of the XML, and I cannot figure out how to query the XML, or the attributes of nodes within that XML.
Here is the type of query I want to do:
SELECT
[regular_table_field1],
[regular_table_field2],
[opt_resposne_xml].rootnode.wrapper.child#attr('someattribute') AS 'someattribute',
[opt_resposne_xml].rootnode.wrapper.child#attr('someattribute2') AS 'someattribute2'
FROM [optimizations] WHERE [opt_concept_id] = '1234'
Not knowing what your XML looks like, here's a general purpose piece of code to give you an idea of what it would look like:
SELECT
[regular_table_field1],
[regular_table_field2],
[opt_resposne_xml].value('(/rootnode/wrapper/child/#someattribute)[1]', 'int') AS 'someattribute',
[opt_resposne_xml].value('(/rootnode/wrapper/child/#someattribute2)[1]', 'varchar(50)') AS 'someattribute2'
FROM
[optimizations]
WHERE
[opt_concept_id] = '1234'
If you need to "reach into" the XML column and grab out a single value (from an XML element or attribute), you basically need to define the XPath to that location of where the information you're interested in is located, and you need to convert that to a given SQL Server datatype.
If you need to have a single relational row cross joined against a number of elements from a single XML field, you might need other approaches (CROSS APPLY).
Also: you might need to pay attention to XML namespaces that are involved - a common pitfall when trying to parse XML inside SQL Server.
I have typed xml as one of the columns in my table (sql server 2008). I need to extract one specific value from this typed xml field. I checked across multiple sites, but only ways to extract a field from untyped xml alone is given. Help me in getting this gone.
If by typed you mean xml that has namespaces, try something like:
WITH XMLNAMESPACES ('http: //www.MySampleCompany.com' AS MY)
SELECT
chapters.node.value('../#title', 'nvarchar(50)') AS bookTitle
FROM #data.nodes('//MY:chapter') AS chapters(node)
Vote down or comment if I misunderstand your question.
Is there a direct route that is pretty straight forward? (i.e. can SQL Server read XML)
Or, is it best to parse the XML and just transfer it in the usual way via ADO.Net either as individual rows or perhaps a batch update?
I realize there may be solutions that involve large complex stored procs--while I'm not entirely opposed to this, I tend to prefer to have most of my business logic in the C# code. I have seen a solution using SQLXMLBulkLoad, but it seemed to require fairly complex SQL code.
For reference, I'll be working with about 100 rows at a time with about 50 small pieces of data for each (strings and ints). This will eventually become a daily batch job.
Any code snippets you can provide would be very much appreciated.
SQL Server 2005 and up have a datatype called "XML" which you can store XML in - untyped or typed with a XSD schema.
You can basically fill columns of type XML from an XML literal string, so you can easily just use a normal INSERT statement and fill the XML contents into that field.
Marc
You can use the function OPENXML and stored procedure sp_xml_preparedocument to easily convert your XML into rowsets.
If you are using SQL Server 2008 (or 2005), it has an xml native datatype. You can associate an XSD schema with xml variables, and Insert directly into columns of type xml.
Yes, SQL Server 2005 and above can parse XML out of the box.
You use the nodes, value and query methods to break it down how you want, whether values or attributes
Some shameless plugging:
Importing XML into SQL Server
Search XML Column in SQL
Xml data and Xml document could have different meaning.
When xml type is good for data, it doesn't save formatting (white spaces removed), so in some cases (e.g. cofiguration files) the best option is nvarchar.
There is a field in my company's "Contacts" table. In that table, there is an XML type column. The column holds misc data about a particular contact. EG.
<contact>
<refno>123456</refno>
<special>a piece of custom data</special>
</contact>
The tags below contact can be different for each contact, and I must query these fragments
alongside the relational data columns in the same table.
I have used constructions like:
SELECT c.id AS ContactID,c.ContactName as ForeName,
c.xmlvaluesn.value('(contact/Ref)[1]', 'VARCHAR(40)') as ref,
INNER JOIN ParticipantContactMap pcm ON c.id=pcm.contactid
AND pcm.participantid=2140
WHERE xmlvaluesn.exist('/contact[Ref = "118985"]') = 1
This method works ok but, it takes a while for the Server to respond.
I have also investigated using the nodes() function to parse the XML nodes and exist() to test if a nodes holds the value I'm searching for.
Does anyone know a better way to query XML columns??
If you are doing one write and a lot of reads, take the parsing hit at write time, and get that data into some format that is more query-able. A first suggestion would be to parse them into a related but separate table, with name/value/contactID columns.
I've found the msdn xml best practices helpful for working with xml blob columns, might provide some inspiration...
http://msdn.microsoft.com/en-us/library/ms345115.aspx#sql25xmlbp_topic4
In addition to the page mentioned by #pauljette, this page has good performance optimization advice:
http://msdn.microsoft.com/en-us/library/ms345118.aspx
There's a lot you can do to speed up the performance of XML queries, but it will never be as good as properly indexed relational data. If you are selecting one document and then querying inside just that one, you can do pretty well, but when your query needs to scan through a bunch of similar documents looking for something, it's sort of like a key lookup in a relational query plan (that is, slow).
If you have a XSD for your Xml then you can import that into your database and you can then build indexes for your Xml data.
Try this
SELECT * FROM conversionupdatelog WHERE
convert(XML,colName).value('(/leads/lead/#LeadID=''xyz#airproducts.com'')[1]', 'varchar(max)')='true'