For years people have talked about an “impedance mismatch” between relational databases and object-oriented languages. Big answers have been proposed to this problem, such as object-relational mapping, but we’ve yet to see a big answer that’s entirely satisfactory — this article is one of a series that tries to break the problem into a set of smaller problems that have simple answers.
Many modern languages, such as Java, Perl, PHP and C#, are derived from C. In C, string literals are written in double quotes, and a set of double quotes can’t span a line break. One advantage of this is that the compiler can give clearer error messages when you forget the close a string. Some C-like languages, such as Java and C# are like C in that double quotes can’t span multiple lines. Other languages, such as Perl and PHP, allow it. C# adds a new multiline quote operator, @”" which allows quotes to span multiple lines and removes the special treatment that C-like languages give to the backslash character (\).
The at-quote is particularly useful on the Windows platform because the backslash used as a path separator interacts badly with the behavior of quotes in C, C++ and many other languages. You need to write
String path="C:\\Program Files\\My Program\\Some File.txt";
With at-quote, you can write
String path=@"C:\Program Files\My Program\Some File.txt";
which makes the choice of path separator in MS-DOS seem like less of a bad decision.
Now, one really great thing about SQL is that the database can optimize complicated queries that have many joins and subselects — however, it’s not unusual to see people write something like
command.CommandText = "SELECT firstName,lastName,(SELECT COUNT(*) FROM comments WHERE postedBy
=userId AND flag_spam='n') AS commentCount,userName,city,state,gender,birthdate FROM user,user
Location,userDemographics WHERE user.userId=userLocation.userId AND user.userId=userDemographi
cs.user_id AND (SELECT COUNT(*) FROM friendsReferred WHERE referringUser=userId)>10 ORDER BY c
ommentCount HAVING commentCount>3";
(line-wrapped C# example) Complex queries like this can be excellent, because they can run thousands of times faster than loops written in procedural or OO languages which can fire off hundreds of queries, but a query written like the one above is a bit unfair to the person who has to maintain it.
With multiline quotes, you can continue the indentation of your code into your SQL:
command.CommandText = @"
SELECT
firstName
,lastName
,(SELECT COUNT(*) FROM comments
WHERE postedBy=userId AND flag_spam='n') AS commentCount
,userName
,city
,state
,gender
,birthdate
FROM user,userLocation,userDemographics
WHERE
user.userId=userLocation.userId
AND user.userId=userDemographics.user_id
AND (SELECT COUNT(*) FROM friendsReferred
WHERE referringUser=userId)>10
ORDER BY commentCount
HAVING commentCount>3
";
Although this might not be quite quite as cool as LINQ, it works with Mysql, Microsoft Access or any database you need to connect to — and it works in many other languages, such as PHP (in which you could use ordinary double quotes.) In languages like Java that don’t support multiline quotes, you can always write
String query =
" SELECT"
+" firstName"
+" ,lastName"
+" ,(SELECT COUNT(*) FROM comments"
+" WHERE postedBy=userId AND flag_spam='n') AS commentCount"
+" ,userName"
+" ,city"
+" ,state"
+" ,gender"
+" ,birthdate"
+" FROM user,userLocation,userDemographics"
+" WHERE"
+" user.userId=userLocation.userId"
+" AND user.userId=userDemographics.user_id"
+" AND (SELECT COUNT(*) FROM friendsReferred"
+" WHERE referringUser=userId)>10"
+" ORDER BY commentCount"
+" HAVING commentCount>3";
but that’s a bit more cumbersome and error prone.