dotNoted

Icon

Observations of .Net development in the wild

SQL Server double pipe string concatenation issue update

The request to bring the ANSI SQL standard double pipe (“||”) operator for string concatenation to SQL Server has gotten some response from MS.

It is mostly positive, seeing as I never harbored hope for it to make it into Katmai SQL Server 2008. “Michael” left it active and noted the large-ish number of votes for the issue. He mentions that SQL Server uses the “+” operator for string concatenation – yes, we know, and we loathe it. Everyone else uses the double pipe, except, as I’ve noted, MySql, which makes, with SQL Server, and interesting pair.

Vote now, if you haven’t, so we can hope for SQL Server 2008 SP1!

Filed under: Getting Data

Improve SQL Server – vote to support the double pipe (“||”) for string concatenation.

ISO 9075 is the official SQL language standard (synonymous with ANSI SQL). It has supported the double pipe for string concatenation since 1999. Almost every other database supports this operator (the tragically broken MySql reinterpretation being the prominent exception – but who cares?), and thus makes generating more universal SQL cleaner and easier… except that SQL Server doesn’t support it.

You can change that. Vote on Connect: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=259291

Filed under: Getting Data

Spec on Mapping Schema for DLinq

Some good info on what will be in the upcoming Jan (or Feb) CTP for Visual Studio ‘Orcas’. It’s hard to commit to a mapping layer technology when this is coming out – even if it is February.

http://download.microsoft.com/download/5/9/c/59cd0dc5-4691-4c3e-840c-66d865f27692/mapping.xps

Filed under: Getting Data

xsd:any and the Unique Particle Attribution constraint

Here’s a beauty –
 
"Wildcard ‘##any’ allows element ‘foo’, and causes the content model to become ambiguous. A content model must be formed such that during validation of an element information item sequence, the particle contained directly, indirectly or implicitly therein with which to attempt to validate each item in the sequence in turn can be uniquely determined without examining the content or attributes of that item, and without any information about the items in the remainder of the sequence."
 
Whew, ok then. So that’s one thing you can do if you are an out of work English Lit major – write prosaic exceptions for Microsoft.
 
You’ll find that when you have an xsd:any element (a "wildcard") in your XSD schema and try to run an XML document through validation using that schema in .Net 2.0. This is because you are violating the Unique Particle Attribution constraint on schema models. (What is a particle? The short, and usually sufficient answer is that it is the ‘abstract base class’ for elements and groups [and wildcards]. The long answer is here.) The Unique Particle Attribution constraint (UPA) states that any given element in an XML document has to be able to be assigned to one and only one declaration in the associated schema. Wildcards can mess with this in much the same way that they mess with your carefully constructed Regular Expressions – they eat too much. Consider the following declaration from a schema:
 
<xsd:sequence> 
    <xsd:element name="foo" type="xsd:string" minoccurs="0" maxoccurs="unbounded"/>  
    <xsd:element name="bar" type="xsd:string" minoccurs="0" maxoccurs="unbounded"/>
    <xsd:any minoccurs="0" maxoccurs="unbounded" processContents="skip"/> 
</xsd:sequence> 

Now if I had the following XML document, all would be well:
<foo>MyFoo</foo>
<bar>MyBar</bar>
<baz>MyBaz</baz>

…but the following would cause problems
<foo>MyFoo</foo>
<bar>MyBar</bar>
<bar>MyBar</bar>

You can see why. Which schema definition do I attribute the second <bar> element to? It could be the element definition or the wildcard. This is what makes the XML validator fall down, or at least should make it, since it violates the standard’s UPA constraint. It seems, however, that the validator in .Net 1.1 didn’t fall down here… I just downloaded the User Interface Process Application Block and compiled and ran the Insurance Client Managment quickstart and it fell down on the provided XML and XSD (the xsd has a wildcard). I’ll have to wait to try it on 1.1 since I don’t have it installed at work here, but my expectation is that it will work – incorrectly work, that is.
 
So, that leaves the question: is xsd:any a useful thing or not, if it breaks content models so easily? There are two camps. The next post on this subject will explore these camps.

Filed under: Getting Data

Knowing the DBMS

I ran into an issue recently where an application was not updating all the values it was supposed to be, and other values were mysteriously changing when they weren’t supposed to. Yea, sounds like a lookup problem. Either keys were being mixed up or values which were not keys were being used to do updates. The latter shouldn’t really be a case, since keys should _always_ be used to do updates (this forms the foundation for the relational model), but sometimes we run into this sort of thing in the wild.
 
At any rate, the problem had manifested itself in counts which were not exactly accurate. We were expecting zero or very near zero records which didn’t have a verification date on them, since the ad-hoc process we generated was supposed to create one based on the last modified date of the profile. However, after running, it turned out that several thousand records weren’t being updated. This sounds like a lot, but it was only about 1 – 2% of all records, so we forgot it temporarily and moved on.
 
Later, we started getting calls that our work to invalidate certain profiles was having an adverse effect, and updating records which it should have been updating. This was a big problem, since it would nag customers about it when there was _nothing wrong_. This is among the last things you’d ever want to do to your customers, for a number of reasons (irritating spam-sensitive users, desensitizing the behavior you want to encourage). This prompted action.
 

I traced the issue to code other than my own (again – whew! – it’s hard being an outsider and lacking the experience of the large institutional platform which everyone else has been living and breathing) – this time to logic which was updating the database in a batch update utility. The problem apparently was an assumption that the code would update correctly because of the position of the boolean check in the conditional statement. There was a two-fold problem to this logic, since the base assumption that the check would short-circuit was incorrect was complicated by the indeterminate (exluding use of the ORDER BY clause, that is) order of results of a SELECT statement. The programmer didn’t seem to know either of these things, which reinforces my belief that _every expert enterprise developer needs to have a firm grasp on database storage and retrieval fundamentals_ as well as near-expert depth of the peculiarities of the chosen vendor specifics. I’m not sure how other platforms do it, but SQL Server doesn’t short circuit OR statements (but it does AND statements). The docs try to lead us astray on this one, but a simple test shows us everything:

CREATE TABLE #Test ( myValue nvarchar(20) )
INSERT INTO #Test VALUES ( 'Test1' )
INSERT INTO #Test VALUES ( 'Test2' )
INSERT INTO #Test VALUES ( 'Test3' )

--The entire "OR" statement is evaluated, and not short circuited, even thought the first value is true (1/0 will return an error)
SELECT * FROM #Test WHERE myValue LIKE 'Test%' OR 1/0 = 1

--The "AND" statement is short-circuted, since T-SQL 8.0 does this for "AND" (1/0 will return an error) SELECT * FROM #Test WHERE 1 = 2 AND 1/0 = 1

--Test 1 will be returned first, even though it is listed 2nd, because the way the inserts happened, and how the loader retrieves the rows into the page buffers, and then how the query engine reads the buffers…
SELECT * FROM #Test WHERE myValue = 'Test2' OR myValue = 'Test' + '1'

Filed under: Getting Data

Accidents happen because of bad drivers

Today, I lament the sorry state of database drivers on high-end platforms.

Probably everyone is familiar with this site (used to be over on Able Consulting):

http://www.carlprothman.net/Default.aspx?tabid=81

Almost everyone is there… and it’s good to see so many play by the Provider, Data Source, User Id, Password set of properties. There are a couple rouges, who insit on having things their way, but even Oracle went along for the joy ride of the developers who have to code against several platforms. All we have to do is remember these properties, and we can create a connection without drudging up the crufty PDF where it is inevitably underdocumented.

Not so with some of the more marginal databases which are seemingly drunk on their success (past or present), such the ilk of Informix and Teradata. They must buck convention and have developers do it _their_ way, which apparently, means they way which they can drop a driver out there and forget about it as the world of data access moves forward. Informix has gotten better with thier latest releases (finally). Teradata remains a psudo-database as far as I can tell. I don’t at all dispute it’s power for what it does so well, but not locking it in an ivory tower of "thou shalt not have an easy time developing applications which access these mountains of data" would be welcome adornment. Another words, the drivers are just not good, and need updating to make them easier to use on modern platforms.

If you are living in the more sane world of neighborly databases, give those 4 above mentioned properties a try in a connection string, and see if the don’t just work. If this is a possible approach, the following code will allow you to test out providers, making sure they are installed first.

string connectString = String.Format("Provider={0};DBCName={1};Database={2};Uid={3};Pwd={4}"

, ProviderTextBox.Text, ServerNameTextBox.Text, DatabaseNameTextBox.Text, UserNameTextbox.Text, PasswordTextbox.Text);

OleDbConnection connection = new OleDbConnection(connectString);

try

{

connection.Open();

StatusLabel.Text =

"Test Succeded!";

}

catch(OleDbException ex)

{

string msg = "";

foreach(OleDbError error in ex.Errors)

{

msg += error.Message +

"rn";

}

MessageBox.Show(

this, msg);

}

finally

{

if(connection != null)

connection.Close();

}

Filed under: Getting Data

When QueryInterface for interface DTS.CustomTask fails

When creating a DTS application with .Net, you will have problems if you don’t run SP3 on your client machine.

QueryInterface for interface DTS.CustomTask failed

<Quote emphasis="added">

When developing a custom task or just manipulating the DTS objects through .Net you may recive the following error:

QueryInterface for interface DTS.CustomTask failed

This error has been fixed in SQL Server 200 Service Pack 2. Make sure you apply the service pack to the SQL Server machine, and any client machines that will be running the .Net code, since DTS is a client side tool.

</Quote>

Installing SP3 to fix the type casting worked. I have it in my head that SQL service packs are for the server, and forget about the client components… I feel that perhaps I’m not the only one.

Filed under: Getting Data