Tuesday, August 19, 2008

Using Linq for SQL with FOR XML procedures

The problem is

I have a stored procedure in MS SQL that ends with SELECT ... FOR XML, and formerly I used XmlReader to access the data from it (by calling SqlCommand.ExecuteXmlReader())

Now I'm trying to figure out how to access to this using LINQ
With VS constructor I drag and drop this procedure into Linq To SQL data class designer.

It creates something like that

public ISingleResult my_Procedure([Parameter(Name="param1", DbType="VarChar(50)")] string param1, ... all other params)
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo) (MethodInfo.GetCurrentMethod())), param1, ... all other params);
return ((ISingleResult)(result.ReturnValue));

Strange thing that actually procedure returns not a sinlgle line but a collection of arbitrary broken XML source (I'm just wondering what parameter controls the size of each piece)

So to put all XML together you need to create a stream (memory stream) or file and an XmlTextWriter object, opened over the stream and a code like that to select all parts of the XML

System.Collections.Generic.IEnumerable rawXMLLines =
my_ProcedureDataContext()).my_Procedure(param1, ....)
my_Procedure => my_Procedure.XML_F52E2B61_18A1_11d1_B105_00805F49916B);

foreach (string rawXML in rawXMLLines)
writer.WriteRaw( rawXML );

Well, not so much development work but...

Seems, that we lost here the main advantage of the
SELECT ... FOR XML clause - an ability to write Xml to the output stream directly from XmlReader (that we get from
ExecuteXmlReader()) , which is the most effective way if you are working with large XML files.

In the example, shown above, the results of the procedure is extracted by LINQ engine to the collection of strings before we start writing these strings one by one into output stream with XmlWriter.

Thursday, August 14, 2008

Strange Oracle behaviour

In our project we have one very complicated query that involves 10 or more tables joined with left joins or inner joins

IN EACH TABLE there was a field DELETED.

Developer who writes a SQL query made a mistake forgetting to add an alias to the DELETED field in the following WHERE clause

select ...
from table1 t1 join table2 t2 on t1.table1_id = t2.table1_id etc...

and what was strange - there were no compilation errors, oracle executes that query but guess from what table it takes DELETED field? I don't know! But not from the first table :) This behaviour leads to the bug that was very hard to find, debug and correct.

Finally when developer corrected where condition, it starts work as expected


It is not the first case that makes me furrious about Oracle!