
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Loading logfiles into a SQL Server DB via XML
I have a lot of logfiles that I want to load into a SQL Server database via a Talend job so that I can preserve the logs without keeping the files in the file system (we generate over 3k log files every day). I do not want to change the jobs to write to the database directly as I don't want the jobs to be dependent on the DB server being available.
I have created a Talend job that can read a log file and convert it to an XML document which I can then send to a SQL Server (2016) stored procedure. The stored procedure is executed, however the contents of the log file are NOT being stored in the database.
I have ruled out the following possible causes:
- connectivity/permissions - I have logged in to SSMS with the account used by the Talend job and executed the procedure (minus the XML header since I have not found a way to have SSMS allow UTF-8)
The stored procedure is:
ALTER
procedure
[myschema].[myProc]
@logXML
as
xml,
@logFile
as
varchar
(max),
as
varchar
(max)
OUT
as
begin
declare
@myAction
varchar
(max);
begin
try
begin
transaction
set
@myAction
=
'inserting log file '
+
@logFile
;
insert
into
[myDB].[mySchema].[myTable]
(
JobName,
LogName,
RunDate,
LogLineNum,
LogLine
)
(
select
logs.value(
'JobName[1]'
,
'varchar(500)'
)
as
JobName,
logs.value(
'LogName[1]'
,
'varchar(500)'
)
as
LogName,
logs.value(
'runDate[1]'
,
'varchar(20)'
)
as
runDate,
lines.value(
'Number[1]'
,
'integer'
)
as
LogLineNum,
lines.value(
'Content[1]'
,
'varchar(max)'
)
as
LogLine
from
@logXML
.nodes(
'/LogFileContents'
)
as
l1(logs),
@logXML
.nodes(
'/LogFileContents/LogLines/Line'
)
as
l2(lines)
);
commit
transaction;
set
=
'SUCCESS'
;
end
try
begin
catch
if @
@TRANCOUNT
>
0
begin
rollback
set
=
'Error '
+
@myAction
+
'. Error code: '
+ @
@ERROR
;
end
end
catch
end
The XML document generated by the Talend job looks like the following:
<?xml version="1.0" encoding="UTF-8"?> // I do
not
have control
of
this - I
get
this "free"
from
Talend
<LogFileContents>
<JobName>myTask</JobName>
<LogName>myLogFile</LogName>
<runDate>YYYYMMDDHHmiss</runDate>
<LogLines>
<Line>
<Number>
1
</Number>
<Content>
1
st Log Message</Content>
</Line>
<Line>
<Number>
2
</Number>
<Content>
2
nd Log Message</Content>
</Line>
...
<Line>
<Number>
Last
</Number>
<Content>
Last
Log Message</Content>
</Line>
</LogLines>
</LogFileContents>
In Talend I have tried passing the XML document to the tDBSP as a document (which results in a Talend Error). It is currently configured to pass the XML document as a String - I had to add the "sendStringParametersAsUnicode=false" to my connection string (additional parameters) to eliminate the "unable to switch encoding" error. When I check the result from the call to the stored proc I get "SUCCESS". I have even tried having the stored proc pass back a non-sense value for the result instead of "SUCCESS" (and the call to the stored proc returned the non-sense value).
In the stored proc I have tried changing the input parameter to a varchar(max) and then converting that to an XML variable via
@logXML
as
varchar
(max),
...
declare
@myXML
xml =
convert
(xml,
@logXML
)
...
from
@myXML
.nodes(...)
as
l1(logs)
@myXML
.nodes(...)
as
l2(lines)
which also did not load the document into the database.
However if I execute the stored procedure via SSMS using the XML Document (only difference is the missing <?xml...> document header):
<LogFileContents>
<JobName>myTask</JobName>
<LogName>myLogFile</LogName>
<runDate>YYYYMMDDHHmiss</runDate>
<LogLines>
<Line>
<Number>
1
</Number>
<Content>
1
st Log Message</Content>
</Line>
<Line>
<Number>
2
</Number>
<Content>
2
nd Log Message</Content>
</Line>
...
<Line>
<Number>
Last
</Number>
<Content>
Last
Log Message</Content>
</Line>
</LogLines>
</LogFileContents>
The entire contents loads as expected (The log file I am testing with has 40 lines and all 40 show up in the database, exactly as I expect).
I have also reviewed the following links - but they are in regards to processing XML files, not XML strings.
I feel like there's something not quite configured right in Talend but I'm not sure where that would be. Any input/guidance would be greatly appreciated.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
I'm not a SQL SERVER stored procedure expert, can you try to pass XML content as a string type? In the job, you can use a tWriteXMLField to write a XML string.
Regards
Shong

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Shong,
Thanks for the info. I have tried using the tWriteXMLField and one positive thing from that is that I was able to eliminate the XML header - the XML header initially caused me issues since Talend usually encodes via UTF-8 but MS SQL Server doesn't accept that XML encoding by default (there is an "Additional Parameter" value I found that allowed the procedure to accept UTF-8 encoding).
Unfortunately, whether I specify the input XML parameter as a string (and convert it to XML via convert(xml, @logXML)) or if I simply declare the input parameter as XML (ALTER procedure [myproc] @logXML as varchar(max)) the stored procedure is not loading the data into the database when called from Talend. I can take the string generated by tWriteXMLField and execute the stored procedure in SSMS (not via Talend) and the XML gets successfully processed into the DB.
Bill.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So it seems that I need to add a tDBCommit after calling the stored procedure - even though the stored procedure has transaction handling inside. It appears to have something to do with the fact that I'm using a tDBConnection for my tDBSP instead of configuring the connection in the tDBSP component.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does it work now if you use a tDBCommit? If you use the DB connection created by tDBConnection, you should use a tDBCommit to commit the changes.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Shong - yes it works now. I'm curious as to why I need a tDBCommit when the stored procedure had a commit in it. The point of having the stored procedure was, in part, to have it handle the transaction rather than having to manage the transaction (and rollback) in Talend. Is this a function of (1) SQL server, (2) Java (seems unlikely as I have worked with Java developers elsewhere who used Oracle PL/SQL stored procedures that handled the transactions) or a (3) design choice by Talend?
