extracting and saving xml results in file using SSIS - sql-server

I am trying to query results as XML from Oracle db using XMLElement and XMLAgg functions which gives me results in CLOB format. Now, when I try to use this query in Data Source flow task in SSIS, I get an error as unsupported data format.
Query:
select XMLElement("root",
XMLAgg(XMLElement("person",
XMLForest(person.first_name, person.last_name)))) AS "XMLResult"
from person
Question:
How do I use this query in SSIS (2008 R2) to avoid that error or any workaround. Further I need to write the results to a file.

You will need to convert the result into VARCHAR or VARCHAR2 datatype as SSIS doesn't support the XML datatype.

Related

Dealing with &#x0D in SSIS

In SSIS, I have a package that deals with dumping data from one table to another. However after the package finishes executing I notice that my column has &#x0D in place of carriage returns.
Below is part of the query that handles this column.
(select cast((text) as varchar(max)) from [table]
where columna = x.columna for xml path (''), type)
Using the type keyword fixed this issue when I was testing this query on the SSMS.
I also encountered another error before then, where I got the message
Column "MyColumn" cannot convert between unicode and non-unicode string data types.
So I had to modify the affected column to output to Unicode Text Stream (DT_NTEXT) in order to avoid any errors (using Unicode String will cause truncation).
in SSIS package, i will assume that you are using OLEDB Source to read data from Sql server.
you can simply use the same sql query as datasource instead of using a Table name
Adding .value('.',nvarchar(max)') to the end of this statement removes all the &#x0D that appears in the result.
Final query should like the following:
(select cast((text) as varchar(max)) from [table1]
where columna = [table2].columna for xml path (''), type).value('.',nvarchar(max)')
This was to fix another issue I was having in SSIS when dealing with special characters and unicode.
The site containing the solution can be found here.

Geography Data Import

I'm trying to import geography data from a CSV file in to SQL server using the bcp (bulk copy tool) but I can't figure out the format. I would like to use something like this in the CSV files but I get errors on the POINT column:
101932694,POINT(44.0586891174316 -69.2067337036133 4326),2014-07-30,24452353
How can I format geography data in the CSV file so bcp will accept it?
OK, it could not find any information on importing human readable geography data using bcp, so I converted the point data:
POINT (44.058689117431641 -69.206733703613281 4326),...
To the binary form:
E6100000010D000000203B4D51C000000020830746400000000000E6B040,...
And put the binary form in my CSV file. bcp seemed to work fine with that.
I don't know anything about BCP, but hopefully this will give you what you need.
Try importing your data to a temporary table as a string, then importing it into the real table with an update.
Inside of SQL Server spatial data is stored like a varbinary, i.e. your point will be stored as
0xE6100000010C010000203B4D51C0FAFFFF1F83074640
If you try and move the data with SSIS, it actually treats it as varbinary, not as spatial. Because of this, a conversion is required to get your string into the correct format.
SELECT GEOGRAPHY::STGeomFromText('POINT(44.0586891174316 -69.2067337036133)', 4326)
or
SELECT GEOGRAPHY::Point(-69.2067337036133,44.0586891174316,4326)
For those reasons, I am guessing BCP does not implicitly recognize the conversion, and you will probably need to do it manually.
CSV => Temp Table =>
INSERT INTO RealTable (GeogColumn) SELECT GEOGRAPHY::STGeomFromText(GeogString,4326) FROM TempTable

SSIS Oracle table w/BLOBs XML to SQL Server table

We have an Oracle table that contains archived data in the table format:
BLOB | BLOBID
Each BLOB is an XML file that contains all the business objects we need.
Every BLOB needs to be read, the XML parsed and put into 1 SQL Server table that will hold all data.
The table has 5 columns R | S | T | D | BLOBID
Sample XML derived from BLOB:
<N>
<E>
<R>33</R>
<S>1</S>
<T>2012-01-25T09:48:43.213</T>
<D>6.9534619e+003</D>
</E>
<E>
<R>33</R>
<S>1</S>
<T>2012-01-25T09:48:45.227</T>
<D>1.1085871e+004</D>
</E>
<E>
<R>33</R>
<S>1</S>
<T>2012-01-25T09:48:47.227</T>
<D>1.1561764e+004</D>
</E>
</N>
There are a few million BLOBs and we want to avoid copying all the data over as an XML column then to a table, instead we want to go BLOB to table in one step.
What is the best approach to doing this with SSIS/SQL Server?
The code below almost does what we are looking for but only in Oracle Developer and only for one BLOB:
ALTER SESSION SET NLS_TIMESTAMP_FORMAT='yyyy-mm-dd HH24:MI:SS.FF';
SELECT b.BLOBID, a.R as R, a.S as S, a.T as T, cast(a.D AS float(23)) as D
FROM XMLTABLE('/N/E' PASSING
(SELECT xmltype.createxml(BLOB, NLS_CHARSET_ID('UTF16'), null)
FROM CLOUD --Oracle BLOB Cloud
WHERE BLOBID = 23321835)
COLUMNS
R int PATH 'R',
S int PATH 'S',
T TIMESTAMP(3) PATH 'T',
D VARCHAR(23) PATH 'D'
) a
Removing WHERE BLOBID = 23321835 gives the following error ORA-01427: single-row subquery returns more than one row since there are millions of BLOBS. Even so is there a way to run this through SSIS? Adding the SQL to the OLE DB Source did not work for pulling the data from Oracle even for 1 BLOB and would result in errors.
Using SQL Server 2012 and Oracle 10g
To summarize, how would we go from a Oracle BLOB containing XML to SQL Server table with business objects derived from XML with SSIS?
I'm new to working with Oracle, any help would be greatly appreciated!
Update:
I was able to get some of my code to work in SSIS by modifying the Oracle Source in SSIS to use the SQL command code above minus the first line,
ALTER SESSION SET NLS_TIMESTAMP_FORMAT='yyyy-mm-dd HH24:MI:SS.FF';
SSIS doesn't like this line.
Error message with the ALTER SESSION line above included:
No column information was returned by the SQL Command
Would there be another way to format the date without losing data? I'll try experimenting more, possible using varchar(23) for the date instead of timestamp.

bulk import of xml data in to sql server

I have a set of xml files that I want to parse the data of and import in to a sql server 2012 database. The provided xml files will be validated against a schema.
I am looking as to what is the best method of doing this is. I have found this: http://msdn.microsoft.com/en-us/library/ms171878.aspx
I am wondering if this is the best way or if there are others?
You have several options:
SSIS XML Source. This does not validate against the schema. If you want to detect and properly handle invalid XML files, create a script task to validate the schema in C#.
Parse the XML in a stored procedure.
Insert the entire XML file in one column. Depending on your schema validation requirements, you can use an untyped or typed XML column. (Or both)
Parse the XML using XPath functions. This is actually very fast.
INSERT INTO SomeTable (Column1, Column2, Column3)
SELECT
YourXmlColumn.value('(/root/col1)[1]','int'),
YourXmlColumn.value('(/root/col2)[1]','nvarchar(10)'),
YourXmlColumn.value('(/root/col3)[1]','nvarchar(2000)'),
YourXmlColumn.value('(/root/col4)[1]','datetime2(0)')
FROM YourXmlTable

How to script VARBINARY to copy it from one DB to another using a script?

I need to generate an SQL insert script to copy data from one SQL Server to another.
So with .net, I'm reading the data a given SQL Server table and write this to a new text file which can then be executed in order to insert this data on other databases.
One of the columns is a VARBINARY(MAX).
How should and can I transform the obtained byte[] into text for the script so that it can still be inserted on the other databases?
SSMS shows this data as hex string. Is this the format to use?
I can get this same format with the following
BitConverter.ToString(<MyByteArray>).Replace("-", "")
But how can this be inserted again?
I tried
CONVERT(VARBINARY(MAX), "0xMyHexString")
This does an insert, but the value is not the same as in the source table.
It turned out you can just directly insert the hex string, no need to convert anything:
INSERT TableName (VarBinColumnName)
VALUES (0xMyHexString)
Just don't ask why I didn't test this directly...
There are two questions on SO that may help:
What is the fastest way to get varbinary data from SQL Server into a C# Byte array?
and
How Do I Insert A Byte[] Into an SQL Server VARBINARY column?

Resources