I'm trying to query out the contents of both "fields" in DTS:Name="ConnectionString". (Specifically, the text that begins with "". There can be multiple - in this example, there's 2.
I can't figure out how to query it. Between the colon and the dts: dts:, I'm stumped
Any help appreciated.
<DTS:Executable xmlns:DTS="www.microsoft.com/SqlServer/Dts" DTS:ExecutableType="SSIS.Package.2">
<DTS:Property DTS:Name="SuppressConfigurationWarnings">0</DTS:Property>
<DTS:ConnectionManager>
<DTS:Property DTS:Name="DelayValidation">0</DTS:Property>
<DTS:ObjectData>
<DTS:ConnectionManager>
<DTS:Property DTS:Name="Retain">0</DTS:Property>
<DTS:Property DTS:Name="ConnectionString">Data Source=myserver;Initial Catalog=mydbname;Provider=SQLNCLI10.1;Integrated Security=SSPI;Auto Translate=false;Application Name=blah;</DTS:Property>
</DTS:ConnectionManager>
</DTS:ObjectData>
</DTS:ConnectionManager>
<DTS:ConnectionManager>
<DTS:ObjectData>
<DTS:ConnectionManager>
<DTS:Property DTS:Name="Retain">0</DTS:Property>
<DTS:Property DTS:Name="ConnectionString">Data Source=myserver2;Initial Catalog=mydb2;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=false;</DTS:Property>
</DTS:ConnectionManager>
</DTS:ObjectData>
</DTS:ConnectionManager>
</DTS:Executable>
It's not totally clear, but I'm assuming you want the connection strings themselves. So, let's imagine the document is in an XML type column called XmlColumn that is in a table called #XmlTable, then you could do this...
;WITH XMLNAMESPACES ('www.microsoft.com/SqlServer/Dts' as dts)
SELECT Con.Str.value('.', 'varchar(400)')
FROM #XmlTable
CROSS APPLY XmlColumn.nodes('//dts:Property[#dts:Name="ConnectionString"]') as Con(Str)
Note, we need to handle the XML namespace using the WITH statement and the semi-colon at the start is not a mistake. Then we pass an XPath expression to the nodes() method of the xml type, in order to retrieve the items you require.
See it in action here at SQL Fiddle.
Related
Basically, my purpose is urbanization context is to retrieve ALL input Datasource (sqlcommand or tableorviewname) and ALL output datasources
I did a first try succesfully with one of our dtsx packages :
SELECT CONVERT(XML, BulkColumn) AS xContent INTO Packages
FROM OPENROWSET(BULK 'F:\Repos\DW_all\DW_all\anaplan_sales_mrr_v2.dtsx', SINGLE_BLOB) AS x;
SELECT
X.Exe.value('(./#DTS:Description)','nvarchar(20)') as description
,X.Exe.value('(./#DTS:ObjectName)','nvarchar(20)') as ObjectName
,X.Exe.value('(./DTS:ObjectData/pipeline/components/component/properties/property)[1]','nvarchar(25)') as TargettedTable
,X.Exe.value('(./DTS:ObjectData/pipeline/components/component/connections/connection/#connectionManagerRefId)[1]','nvarchar(100)') as TargettedConnect
,X.Exe.value('(./DTS:ObjectData/pipeline/components/component[2]/properties/property[1]/#name)[1]','nvarchar(max)') as SourceType
,X.Exe.value('(./DTS:ObjectData/pipeline/components/component[2]/properties/property)[1]','nvarchar(max)') as [Source]
,X.Exe.value('(./DTS:ObjectData/pipeline/components/component[2]/connections/connection/#connectionManagerRefId)[1]','nvarchar(100)') as SourceConnect
FROM (SELECT XContent AS pkgXML FROM [dbo].[TestPackage]) t
CROSS APPLY pkgXML.nodes('/DTS:Executable/DTS:Executables/DTS:Executable/DTS:Executables/DTS:Executable') X(Exe)
Where X.Exe.value('(./#DTS:Description)[1]','nvarchar(max)') = 'Data Flow Task'
RESULT :
description
ObjectName
TargettedTable
...
Data Flow Task
1rst flowname
First Table
Data Flow Task
Other Flow
other Table
Data Flow Task
Another Flow
another table
Well, till now everything's fine.
Unfortunately, the properties position and the path is now always the same. In my exemple above, target is the first tag in the XML file (that's why [1]) and source is mentioned after (that's why [2]). But in other packages, that's the reverse case.
In the same idea, the property indicating the type of the datasource (name=sqlcommand or name=tableorviewname) is not always in the same position, so the pointer [1] is not relevant.
Moreover, in my exemple above the path is '/DTS:Executable/DTS:Executables/DTS:Executable/DTS:Executables/DTS:Executable' (with one Sequence Container) but other packages don't have container and have a different path (ex: /DTS:Executable/DTS:Executables/DTS:Executable').
I have tried some test with kind of wildcard like [.] or [*] but i'm not confortable with this and my tests are still on failure.
<DTS:ObjectData xmlns:DTS="DTS">
<pipeline
version="1">
<components>
<component
refId="Package\blabla my description id"
componentClassID="Microsoft.OLEDBSource"
contactInfo="OLE DB Source;Microsoft Corporation; Microsoft SQL Server; (C) Microsoft Corporation; All Rights Reserved; http://www.microsoft.com/sql/support;7"
description="OLE DB Source"
name="My DataFlow Name"
usesDispositions="true"
version="7">
<properties>
<property
dataType="System.Int32"
description="The number of seconds before a command times out. A value of 0 indicates an infinite time-out."
name="CommandTimeout">0</property>
<property
dataType="System.String"
description="Specifies the name of the database object used to open a rowset."
name="OpenRowset"></property>
<property
dataType="System.String"
description="Specifies the variable that contains the name of the database object used to open a rowset."
name="OpenRowsetVariable"></property>
<property
dataType="System.String"
description="The SQL command to be executed."
name="SqlCommand"
UITypeEditor="Microsoft.DataTransformationServices.Controls.ModalMultilineStringEditor, Microsoft.DataTransformationServices.Controls, Version=15.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91">SELECT * From OneTable Inner Join AnotherTable ...
</property>
</properties>
</component>
</components>
</pipeline>
</DTS:ObjectData>
Can anyone help me please to improve the initial script to make it efficient for whatever packages, resulting all sqlcommand or tableorviewname in input of the dataflows included in the package, and the same in output.
TIA for your help and advices :-)
Fred.M.
I have an XML document that I'm working to build a schema for in order to bulk load these documents into a SQL Server table. The XML I'm focusing on looks like this:
<Coverage>
<CoverageCd>BI</CoverageCd>
<CoverageDesc>BI</CoverageDesc>
<Limit>
<FormatCurrencyAmt>
<Amt>30000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>PerPerson</LimitAppliesToCd>
</Limit>
<Limit>
<FormatCurrencyAmt>
<Amt>85000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>PerAcc</LimitAppliesToCd>
</Limit>
</Coverage>
<Coverage>
<CoverageCd>PD</CoverageCd>
<CoverageDesc>PD</CoverageDesc>
<Limit>
<FormatCurrencyAmt>
<Amt>50000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>Coverage</LimitAppliesToCd>
</Limit>
</Coverage>
Inside the Limit element, there's a child LimitAppliesToCd that I need to use to determine where the Amt element's value actually gets stored inside my table. Is this possible to do using the standard XML Bulk Load feature of SQL Server? Normally in XML I'd expect that the element would have an attribute containing the "PerPerson" or "PerAcc" information, but this standard we're using does not call for that.
If anyone has worked with the ACORD standard before, you might know what I'm working with here. Any help is greatly appreciated.
Don't know exactly what you are talking about, but this is a solution to get the information out of your XML.
Assumption: Your XML is already bulk-loaded into a declared variable #xml of type XML:
A CTE will pull the information out of your XML. The final query will then use PIVOT to put your data into the right column.
With a fitting table's structure the actual insert should be simple...
WITH DerivedTable AS
(
SELECT cov.value('CoverageCd[1]','varchar(max)') AS CoverageCd
,cov.value('CoverageDesc[1]','varchar(max)') AS CoverageDesc
,lim.value('(FormatCurrencyAmt/Amt)[1]','decimal(14,4)') AS Amt
,lim.value('LimitAppliesToCd[1]','varchar(max)') AS LimitAppliesToCd
FROM #xml.nodes('/root/Coverage') AS A(cov)
CROSS APPLY cov.nodes('Limit') AS B(lim)
)
SELECT p.*
FROM
(SELECT * FROM DerivedTable) AS tbl
PIVOT
(
MIN(Amt) FOR LimitAppliesToCD IN(PerPerson,PerAcc,Coverage)
) AS p
My database component has the following configuration
<db:insert config-ref="Oracle_Configuration" bulkMode="true" doc:name="Database">
<db:dynamic-query><![CDATA[#[flowVars.dbquery]]]></db:dynamic-query>
</db:insert>
I have declared the "dbquery" variable as follows
<set-variable variableName="dbquery" value="INSERT INTO WBUSER.EMP VALUES('#[payload.FullName]','#[payload.SerialNumber]')" doc:name="Variable"/>
On running the application the values inserted into the DB are "#[payload.FullName] and #[payload.SerialNumber].
But when my database component has the following configuration actual values of FullName and SerialNumber are getting inserted into the database.
<db:insert config-ref="Oracle_Configuration" bulkMode="true" doc:name="Database">
<db:dynamic-query><![CDATA[INSERT INTO WBUSER.EMP VALUES('#[payload.FullName]','#[payload.SerialNumber]')]]></db:dynamic-query>
</db:insert>
Here FullName and SerialNumber are not variables. They are column names of the list in the payload as [{FullName=yo, SerialNumber=129329}, {FullName=he, SerialNumber=129329}].
Can someone tell me the difference here. And is there a way i can achieve database insertion using just the variable as in the earlier case?
It caused by different approach to insert data. It works correctly for the configuration inside db-insert, because the payload is in form of List and Bulk Mode option selected.
To make it work for the first configuration (declare SQL query in a variable) then you have to do the following steps:
Iterate each payload value by utilizing: collection-splitter.
Deselect Bulk Mode from database connector.
The configuration should be:
<collection-splitter doc:name="Collection Splitter"/>
<set-variable variableName="dbquery" value="INSERT INTO WBUSER.EMP VALUES('#[payload.FullName]','#[payload.SerialNumber]')" doc:name="Variable"/>
<db:insert config-ref="MySQL_Configuration" doc:name="Database">
<db:dynamic-query><![CDATA[#[flowVars.dbquery]]]></db:dynamic-query>
</db:insert>
I need to get some information from XML in SQL Server 2008, but I cannot even get basic attribute from it. All samples that I tried failed. Table name is Item, xml column name is Data.
Simplified xml looks like this:
<AnchoredXml xmlns="urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008" SchemaWriteVersion="2">
<Key ScopeClass="Global">
<SchemaId Namespace="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" ElementName="Topology" />
<AuthorityId Class="Host" InstanceId="00000000-0000-0000-0000-000000000000" />
</Key>
<Dictionary Count="1">
<Item>
<Key />
<Value Signature="a3502dd0-8c16-4023-9eea-30ea1c7a3a2b">
<Topology xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008">
<Services>
<Service RoleVersion="1" ServiceVersion="6" Type="Microsoft.Rtc.Management.Deploy.Internal.ServiceRoles.FileStoreService">
<ServiceId SiteId="1" RoleName="FileStore" Instance="1" />
<DependsOn />
<InstalledOn>
<ClusterId SiteId="1" Number="1" />
</InstalledOn>
<Ports xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.ServiceRoles.2008" />
<FileStoreService xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.ServiceRoles.2008" ShareName="lyncShare" />
</Service>
</Services>
</Topology>
</Value>
</Item>
</Dictionary>
</AnchoredXml>
I need to read information in AnchoredXml/Key/SchemaId/#NameSpace to select the right xml (there are more rows). Sample xml above is the right one. And after that I need to find the right service with
Type="Microsoft.Rtc.Management.Deploy.Internal.ServiceRoles.FileStoreService"
where is FileStoreService/#ShareName that I need.
I've tried to print the Namespace attributte for the start, but no sample code is working.
A few tries:
SELECT c.p.value('(#Namespace)[1]', 'varchar(50)') as 'Nmspace'
FROM Item
CROSS APPLY Data.nodes('/AnchoredXml/Key/SchemaId') c(p)
returns empty result set
SELECT Data.value('(/AnchoredXml/Key/SchemaId/#Namespace)[1]', 'varchar(50)')
FROM Item
returns NULL for all rows
SELECT
It.Data.exist('/AnchoredXml/Key/SchemaId[#Namespace="Microsoft.Rtc.Management.Deploy.Topology.2008"]')
FROM [xds].[dbo].[Item] AS It
returns 0's for all rows also without quotes ("")
A working sample code to get at least attribute test would be maybe sufficient and I would figure out the rest.
Could you please help me find errors in my queries or maybe identify some other problem?
Thanks
You're ignoring all the XML namespaces in your XML document! You need to pay attention to those and respect them!
There are XML namespaces on:
the root node <AnchoredXml>
(XML namespace: urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008)
the subnode <Topology>
(XML ns: urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008)
the subnode <FileStoreService>
(XML ns: urn:schema:Microsoft.Rtc.Management.Deploy.ServiceRoles.2008)
Try this:
-- respect the XML namespaces!!
;WITH XMLNAMESPACES(DEFAULT 'urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008',
'urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008' AS t,
'urn:schema:Microsoft.Rtc.Management.Deploy.ServiceRoles.2008' AS fss)
SELECT
ShareName = Data.value('(/AnchoredXml/Dictionary/Item/Value/t:Topology/t:Services/t:Service/fss:FileStoreService/#ShareName)[1]', 'varchar(50)')
FROM
dbo.Item
In my case, this returns:
ShareName
-----------
lyncShare
We are in the process of upgrading our sql server to 2K8 R2 and the output of a FOR XML AUTO query has changed.
The query outputs columns from three tables
The resultset returns three rows which each column is identical bar the last two columns from the third table. the results used to show as below
<element1 myval="Test">
<element2 myotherval="atest">
<element3 a="a"/>
<element3 a="b"/>
<element3 a="c" />
</element2>
</element1>
it not shows
<element1 myval="Test">
<element2 myotherval="atest">
<element3 a="a"/>
</element2>
</element1>
<element1 myval="Test">
<element2 myotherval="atest">
<element3 a="B"/>
</element2>
</element1>
<element1 myval="Test">
<element2 myotherval="atest">
<element3 a="C"/>
</element2>
</element1>
I have been trying to use For XML Path but it still returns 3 separate instances of element1 rather than grouping the data.
If you want a subtree using FOR XML PATH, you'll have to write subqueries for each subtree. So in your case you have a parent select statement for element1, and one of the columns is a subquery that gets whatever needs to be in element2 (which in turn can also be subqueries). If you use subqueries and you want XML returned from those, use
FOR XML PATH('elementN'), TYPE
or it'll escape the XML code.