I want to generate a XML file from a table
But my xmlelement doesn't have the same name that the column in the table
How can I do that?
And I want to generate something like this:
<Car>
<Brand>Ford</Ford>
<Color>Blue</Color>
</Car>
How can I specify the childnodes in my XMl file?
This is covered in the FOR XML documentation, especially in the Using PATH Mode examples.
create table dbo.ThisIsNotTheTableYouAreLookingFor (
NorIsThis varchar(10),
TheColumn varchar(10)
);
insert dbo.ThisIsNotTheTableYouAreLookingFor (NorIsThis, TheColumn)
values ('Ford', 'Blue');
select
NorIsThis as Brand,
TheColumn as Color
from dbo.ThisIsNotTheTableYouAreLookingFor
for xml path('Car');
<Car>
<Brand>Ford</Brand>
<Color>Blue</Color>
</Car>
Related
I have a table that has mixed column types (int, varchar, & xml). The varchar columns have XML formatted data and the xml column has a large node of data. I'm trying to select all the varchar columns with the XML included to create an XML output file using a SQL Agent job step. The problem I'm having is the column defined as XML is padding a lot of spaces in the file and is truncating data in that column. Table is as follows:
CREATE TABLE [dbo].[MixedTYPEXML](
[col1] [varchar](4) NOT NULL,
[col2] [int] NOT NULL,
[xmlinText1] [varchar](190) NOT NULL,
[JOBP] [xml] NULL
)
GO
INSERT INTO [dbo].[MixedTypeXML]
([col1]
,[col2]
,[xmlinText1]
,[JOBP]
)
VALUES
('Prod'
,'35490'
,'<JOBP AllowExternal="1" name="JOBP.EXTRACTS_PHP_SSIS_POST_CORE#35490">'
,'<PreCon><conditions id="CONDITIONS" /></PreCon>'
)
GO
My select statement is
SELECT col2, xmlinText1, JOBP from dbo.MixedTypeXML
The expected results are below but the actual would be several thousand records. I'm only pulling one record with a small sample data example.
35490 <JOBP AllowExternal="1" name="JOBP.EXTRACTS_PHP_SSIS_POST_CORE#35490"> <PreCon><conditions id="CONDITIONS" /></PreCon>
This is just a subset of the columns I'm trying to extract. I basically need to extract all the columns in the table including the XML defined column to send the results to an output table on the local drive without padding spaces or truncating the data. The output file will be an XML formatted file. The JOBP column sample data is just a snippet. The actual data contains a few hundred lines of xml nodes.
I've looked at lots of posts on how to extract nodes and values but I'm not trying to extract specific data. I want the entire table to create an XML output file. Any ideas how to do that?
Based on the desired output, the entire output file shall be in XML format. It cannot be partially *.csv file mixed with XML elements.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (
[col1] VARCHAR(4) NOT NULL,
[col2] INT NOT NULL,
[xmlinText] VARCHAR(190) NOT NULL,
[JOBP] XML NULL
);
INSERT INTO #tbl ([col1] ,[col2] ,[xmlinText] ,[JOBP])
VALUES
(
'Prod'
,35490
,'<JOBP AllowExternal="1" name="JOBP.EXTRACTS_PHP_SSIS_POST_CORE#35490"/>'
,'<PreCon><conditions id="CONDITIONS" /></PreCon>'
)
-- DDL and sample data population, end
SELECT col1, col2
, TRY_CAST([xmlinText] AS XML) AS [xmlinText]
, JOBP
FROM #tbl
FOR XML PATH('row'), TYPE, ROOT('root');
Output
<root>
<row>
<col1>Prod</col1>
<col2>35490</col2>
<xmlinText>
<JOBP AllowExternal="1" name="JOBP.EXTRACTS_PHP_SSIS_POST_CORE#35490" />
</xmlinText>
<JOBP>
<PreCon>
<conditions id="CONDITIONS" />
</PreCon>
</JOBP>
</row>
</root>
None of the above answers worked for me. What I finally got to work was using the CONVERT string feature.
SELECT col1, col2
, CONVERT(VARCHAR(MAX), JOBP)
FROM #tbl
Encountering an issue while attempting to convert some special characters into proper XML. Instead, it's returning XML which is failing for the calling application.
This is part of a much larger chunk of code. I must use XML PATH, otherwise it will require refactoring the entire procedure, which is outside the scope of this work.
I have attempted to replace the values, and tried replacing the values both before and after. I'm unable to perform an extra pass on the subsequent returned XML
DROP TABLE IF EXISTS #MyData
GO
CREATE TABLE #MyData
(
RefId varchar(20) NOT NULL,
Company varchar(255) NOT NULL
);
GO
INSERT INTO #MyData (RefId, Company) VALUES ('SN7172', 'Goodle '+CHAR(0174));
INSERT INTO #MyData (RefId, Company) VALUES ('GW5282', 'NewtownApple '+CHAR(0169));
INSERT INTO #MyData (RefId, Company) VALUES ('ZE0018', 'Curlewky Appliances '+CHAR(0151));
INSERT INTO #MyData (RefId, Company) VALUES ('TW1037', 'Sparky Games '+CHAR(0153));
GO
SELECT (
SELECT RefId,
REPLACE(REPLACE(REPLACE(REPLACE(Company, char(0174),'®'), char(0169),'©'), char(0153),'™'), char(0151),'—') Company
FROM #MyData
FOR XML PATH('Catalog'), TYPE
)
FOR XML PATH('Catalogs'), TYPE
The SQL is being converted to ® instead of ®
Yet, the XML below shows the ampersand being converted, rather than the full string.
<Catalog>
<RefId>GW5282</RefId>
<Company>Newtown & Apple ©</Company>
</Catalog>
<Catalog>
<RefId>ZE0018</RefId>
<Company>Curlewky Appliances —</Company>
</Catalog>
<Catalog>
<RefId>TW1037</RefId>
<Company>Sparky Games ™</Company>
</Catalog>
</Catalogs>
Do I get this correctly? The XML your SQL-Server produces is correct (something like <Company>NewtownApple ©</Company>), but your consumer cannot deal with the © and therefore you want to use the entity instead. Correct?
One hack might be to convert the resulting XML and do the replacements there on string base:
SELECT REPLACE(REPLACE(REPLACE(REPLACE(CAST(
(
SELECT (
SELECT RefId, Company
FROM #MyData
FOR XML PATH('Catalog'), TYPE
)
FOR XML PATH('Catalogs'), TYPE) AS nvarchar(MAX)), char(0174),'®'), char(0169),'©'), char(0153),''), char(0151),'');
But do not try to cast the result back to XML. You would get the special characters back...
I have a stored procedure that will receive an xml document I will be processing. Depending on the different processes that will call this procedure, I will be inserting data into a temp table from this openxml prepared document that will be from one group or another.
Ex: It could be:
FROM OPENXML(#idoc, '/data/BeneInfoGroup/BeneInfo', 1)
OR it could be:
FROM OPENXML(#idoc, '/data/PersonalInfoGroup/PersonalInfo', 1)
Only one group will come through. Depending on this group - I want to create an SQL string (to be EXECUTED) that inserts into a temp table (already created) and contains field names from the openxml doc.
So my code (in the 2 examples above) could look like:
strSQL = N'INSERT INTO #tmpTbl (BeneID, BeneSSN, BeneDate)
SELECT BeneID, BeneSSN, BeneDate
FROM OPENXML(#idoc, ''/data/BeneInfoGroup/BeneInfo'', 1)
WITH (BeneID nvarchar(50) ''BeneID'', BeneSSN nvarchar(50) ''BeneSSN'', BeneDate nvarchar(50) ''BeneDate'')'
Or it could look like:
strSQL = N'INSERT INTO #tmpTbl (PersonID, PersonSSN, PersonDate)
SELECT PersonID, PersonSSN, PersonDate
FROM OPENXML(#idoc, ''/data/PersonInfoGroup/PersonInfo'', 1)
WITH (PersonID nvarchar(50) ''PersonID'', PersonSSN nvarchar(50) ''PersonSSN'', PersonDate nvarchar(50) ''PersonDate'')'
The 2 examples above are minimal. It won't be "Person" vs "Bene" headers. The fields could be named anything in either group. So I'd like to loop through the openxml document and have the fieldnames go into my string where appropriate. I can take care of the data type details, etc. I just need to pull the field names from the openxml doc I've prepared.
I do NOT need an alternative method using something other than OPENXML, please.
The basic question is - how do I pull the field name from the document in a way that's not hard coded depending on the xml doc I receive?
I don't want to create a table of the field names.
I just want to go through a loop and reference every fieldname that exists for that particular group in my openxml.
No need to worry about #tmpTbl - I have created this with all possible fields that might be inserted into it.
Thanks in advance! Daniel
I'm working on a SSIS Package.
I have a table as below:
Table Name: Employee_table
EmployeID EmployeeName EmployeeDataXML
==============================================
1 Mark <Age>32</Age><Role>Manager</Role>
2 Albert <Age>31</Age><Role>Staff</Role>
==============================================
This table has to be exported into a flat file with name: Employeedata.dat
Content in the file should look like this:
<EmployeeID>1</EmployeeID><EmployeeName>Mark</EmplyeeName><EmployeeDataXML><Age>32</Age><Role>Manager</Role></EmployeeDataXML>
<EmployeeID>2</EmployeeID><EmployeeName>Albert</EmplyeeName><EmployeeDataXML><Age>31</Age><Role>Staff</Role></EmployeeDataXML>
Basically, the employeeid and employeename columns are not in xml format but still when the export happens they should be wrapped up in xml too.
Can someone guide me which is the best way to do it?
Do i need to use any transformation here?
Is there any control/task which is readily available?
Can writing a SQL Select Statement which could simply solves this?
Please guide.
Yes, a simple SELECT using FOR XML PATH should take care of this:
DECLARE #TestData TABLE
(
EmployeID INT NOT NULL,
EmployeeName NVARCHAR(50) NOT NULL,
EmployeeDataXML XML
);
INSERT INTO #TestData (EmployeID, EmployeeName, EmployeeDataXML)
VALUES (1, N'Mark', N'<Age>32</Age><Role>Manager</Role>');
INSERT INTO #TestData (EmployeID, EmployeeName, EmployeeDataXML)
VALUES (2, N'Albert', N'<Age>31</Age><Role>Staff</Role>');
SELECT EmployeID, EmployeeName, EmployeeDataXML
FROM #TestData
FOR XML PATH(N'Employee');
produces the following:
<Employee>
<EmployeID>1</EmployeID>
<EmployeeName>Mark</EmployeeName>
<EmployeeDataXML>
<Age>32</Age>
<Role>Manager</Role>
</EmployeeDataXML>
</Employee>
<Employee>
<EmployeID>2</EmployeID>
<EmployeeName>Albert</EmployeeName>
<EmployeeDataXML>
<Age>31</Age>
<Role>Staff</Role>
</EmployeeDataXML>
</Employee>
You didn't have the parent <Employee> element shown in the sample output, but I don't think the file would be usable without some element wrapping the field elements into a "row".
I have the following T-SQL query that I want to convert into XML file. I was trying to use FOR XML Path, but this isn't working the way I need it to.
Here is my T-SQL table definition:
create table TN_DataFeed
(
--Patient uniqueidentifier,
ProviderPatientNo varchar(50) null,
LastName varchar(25),
FirstName varchar(25),
SSN char(9) null,
DOB char(10) null,
Gender tinyint null,
Race tinyint null,
Ethnicity tinyint null,
--PhoneAssessment varchar(50),
ProviderPhoneAssessmentID varchar(50),
CallEndDate char(10),
CallEndTime varchar(8)
)
My data matches this format above and successfully is inserted. But I need my XML to look like:
<Patient>
<ProviderPatientNo>ProviderPatientNo0</ProviderPatientNo>
<LastName>LastName0</LastName>
<FirstName>FirstName0</FirstName>
<SSN>000000000</SSN>
<DOB>2006-05-04</DOB>
<Gender>1</Gender>
<Race>1</Race>
<Ethnicity>1</Ethnicity>
<PhoneAssessment>
<ProviderPhoneAssessmentId>52854541</ProviderPhoneAssessmentId>
<CallEndDate>2006-05-04</CallEndDate>
<CallEndTime>01:01:01.001</CallEndTime>
</PhoneAssessment>
</Patient>
This is my XML Path code for retrieving the above T-SQL query:
select
ProviderPatientNo,
LastName,FirstName,SSN,DOB,Gender,Race,Ethnicity,
(
select distinct
ProviderPhoneAssessmentId, CallEndDate, CallEndTime
from TN_DataFeed
For XML path ('PhoneAssessment'), root('PhoneAssessment2'), type
)
from TN_DataFeed
For XML path ('Patient'), root('Patient_root'), type
Note that I have not yet included all of the columns. Instead, I'm just trying to get the Patient section working. Notice how in the example XML file below, the section that shows how Patient is the parent node of ProviderPatientNo, LastName, FirstName, SSN, DOB, Gender, Race, and Ethnicity.
But instead, my XML output from my above XML Path is:
<Patient_root>
<Patient>
<ProviderPatientNo>00200543</ProviderPatientNo>
<LastName>Ga</LastName>
<FirstName>Ti</FirstName>
<SSN>4108</SSN>
<DOB>1998-08-16</DOB>
<Gender>2</Gender>
<Race>2</Race>
<Ethnicity>3</Ethnicity>
<PhoneAssessment2>
<PhoneAssessment>
<ProviderPhoneAssessmentId>BEA5487B-82E9-4226-B883-BFBFE7EF2B1A</ProviderPhoneAssessmentId>
<CallEndDate>2013-09-16</CallEndDate>
<CallEndTime>22:00:00</CallEndTime>
</PhoneAssessment>
<PhoneAssessment>
<ProviderPhoneAssessmentId>C8F39E2F-BC4A-48AD-BD07-C07EB8384AD7</ProviderPhoneAssessmentId>
<CallEndDate>2013-09-16</CallEndDate>
<CallEndTime>16:24:00</CallEndTime>
</PhoneAssessment>
</PhoneAssessment2>
</Patient>
<Patient>
<ProviderPatientNo>00200543</ProviderPatientNo>
<LastName>Ga</LastName>
<FirstName>Ti</FirstName>
<SSN>4108</SSN>
<DOB>1998-08-16</DOB>
<Gender>2</Gender>
<Race>2</Race>
<Ethnicity>3</Ethnicity>
<PhoneAssessment2>
<PhoneAssessment>
<ProviderPhoneAssessmentId>BEA5487B-82E9-4226-B883-BFBFE7EF2B1A</ProviderPhoneAssessmentId>
<CallEndDate>2013-09-16</CallEndDate>
<CallEndTime>22:00:00</CallEndTime>
</PhoneAssessment>
<PhoneAssessment>
<ProviderPhoneAssessmentId>C8F39E2F-BC4A-48AD-BD07-C07EB8384AD7</ProviderPhoneAssessmentId>
<CallEndDate>2013-09-16</CallEndDate>
<CallEndTime>16:24:00</CallEndTime>
</PhoneAssessment>
</PhoneAssessment2>
</Patient>
So the problems are:
Many of the elements are repeated. I tried using Distinct to limit repetitions, but this caused the error:
The xml data type cannot be selected as DISTINCT because it is not
comparable.
Ok: First thing I notice is that you're querying the information_schema not the actual table, and all this gives you is the table schema metadata. Can you change your query to query the table please? SELECT ... FROM TN_DataFeed.
See this example : http://technet.microsoft.com/en-us/library/bb510462.aspx
Something like this should get you close to what you want:
SELECT ProviderPatientNo,
LastName,
FirstName,
SSN,
DOB,
Gender,
Race,
PhoneAssessment ....
FROM TN_DataFeed
FOR XML PATH ('Patient');
you can replace the distinct with a GROUP BY
select
ProviderPhoneAssessmentId, CallEndDate, CallEndTime
from
TN_DataFeed
group by
ProviderPhoneAssessmentId, CallEndDate, CallEndTime