DOWNLOAD THE CODE:
Download the Code 94378.zip

Remember that when none of the items in the CASE expression yields true and there's no ELSE element, the CASE expression uses an implicit ELSE NULL element. This particular CASE expression converts val to an integer when val contains only digits. The logical expression T1.val NOT LIKE '%[^0-9]%' is simplistic and doesn't cover all cases of valid or invalid integers. But again, this is just an example. You can enhance this CASE expression to make it more robust and more accurate in terms of verifying that val is convertible to an integer.

As I mentioned earlier, I consider the discrepancy between physical and logical query-processing order to be a bug, but in the same breath I should say that I consider it an acceptable bug. The other option is to compromise performance, which is a less acceptable option than having the query fail, in this case. At least, when a failure occurs, you can take steps to avoid it by using one of the methods I've discussed.

Another situation is somewhat similar, but you shouldn't consider it a bug since it doesn't conflict with standard SQL. To demonstrate this condition, run the code in Listing 3 to create the table T1 and populate it with sample data. Look at the following query and before you run it, see if you can tell whether or not it should fail:

SELECT keycol, val
  FROM dbo.T1 
WHERE val * 0.5 >= 1
AND 10 / val <= 5;

Now run the query. When I ran this query in SQL Server 2005, I got the following divide by-zero error: Msg 8134, Level 16, State 1, Line 1, Divide by zero error encountered.

Many programming languages (such as C) physically evaluate logical expressions from left to right and short-circuit as soon as the result is known. For example, when val is zero, the expression val * 0.5 >= 1 is false, so there's no reason to evaluate the next expression. Had SQL worked the same way, such a query shouldn't have failed. But SQL differs from other programming languages in many ways. Each phase in logical query processing is considered an all-at-once operation. Thus, SQL Server logically processes all logical expressions in the WHERE phase at the same time. In physical terms, SQL Server

does support short-circuits, but it's free to evaluate the expressions in a particular phase in any order that it deems fit. The physical order of evaluation isn't necessarily left to right, rather it's driven by cost estimations. This is why I don't think that a failure in such a case can be considered a bug.

Can you do anything to resolve the issue? Yes, by using a similar technique to the one I showed in the previous scenario: a CASE expression like the one in Listing 4, in which you have full control over the order of evaluation. This query runs with no failure and returns the result set that Table 2 shows.

Circumvent Conflicts
You should be aware that in SQL Server 2005, physical query processing isn't necessarily in agreement with logical query processing for the sake of performance—even when this disparity causes query failure. However, in cases when you do get a query failure, you should reexamine the design of your tables. If you can't change their design, you can use CASE expressions to control the order in which the optimizer evaluates query elements for processing. Also, remember the all-at-once concept. Logical expressions aren't necessarily evaluated physically from left to right. But in scenarios where you need to control the order of evaluation, you can do so by using CASE expressions.

End of Article

Prev. page     1 [2]     next page -->



You must log on before posting a comment.

If you don't have a username & password, please register now.

 
 

ADS BY GOOGLE