![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| ||||
| ||||
|
|
We have two SQL Servers set up, using mirroring. Today we finally got around to testing the "Failover Partner" connection string attribute within a .net application and found that it errored because of a non-declared stored procedure parameter. Turns out it was declared, but it was declared as @userID and then later used in the WHERE clause as @userId (note the lower case 'd'). OK, stop here for a bit. Did you test if the client failed *only* on the |
|
So, case-sensitivity seems to be the issue (as well as a not very well checked stored procedure!).. Well... it's subtle. |
|
I've looked at the database that is mirrored and it is set to LATIN1_GENERAL_CS_AI. |
|
But here's the weird bit. The primary server is set to LATIN1.GENERAL_CI_AS, and the secondary(failover) server is set to LATIN1_GENERAL_CS_AI So, our servers are not configured the same - I'm still ok with this so far, and changing the server collation on the secondary(failover) should resolve this (I hope), but the bit that's confusing me is that I thought that the 'database' collation setting would over ride the default of the server, but it seems that the server collation is over riding the database's? |
#3
| |||
| |||
|
|
Even if the database is using a case-sensitive collation, stored procedure parameter names are not case sensitive within the stored procedure, at least not if the server collation is case-insensitive (at least in my tests; I had no opportunity to try it with a case-sensitive server collation). So the stored procedure is not at fault. |
|
A case-sensitive collation on your database is supremely evil. Alright, not *supremely* evil, but very awkward for most use cases. |
#4
| ||||
| ||||
|
|
Jeroen Mostert (jmostert (AT) xs4all (DOT) nl) writes: Even if the database is using a case-sensitive collation, stored procedure parameter names are not case sensitive within the stored procedure, at least not if the server collation is case-insensitive (at least in my tests; I had no opportunity to try it with a case-sensitive server collation). So the stored procedure is not at fault. Obviously the procedure is not a fault, as the error is in the application. But variables always follow the server collation. Consider this script: CREATE DATABASE CI COLLATE Latin1_General_CI_AS go USE CI go CREATE PROCEDURE sp AS DECLARE @i int = 1 DECLARE @I int = 2 go EXEC sp go CREATE PROCEDURE sp1 AS ^ DECLARE @i int = 1 SELECT @I = 2 go EXEC sp2 ^ |
|
gi ^^ |
|
USE tempdb go DROP DATABASE CI I get this output when I run it on my server which has Finnish_Swedish_CS_AS as the server collation: Msg 137, Level 15, State 1, Procedure sp1, Line 3 Must declare the scalar variable "@I". Msg 2812, Level 16, State 62, Line 1 Could not find stored procedure 'sp2'. That is, the first procedure compiles, the second fails to compile. |
|
A case-sensitive collation on your database is supremely evil. Alright, not *supremely* evil, but very awkward for most use cases. As this exercise shows, there is a use-case where case-sensitive collations are essential: development environments. In my opinion, you should always develop in a case-sensitive environment, exactly to avoid this sort of problems. In SQL 2012, there is a new feature that evades this problem: contained databases. In a contained database, the collation for metadata is always the one and the same, Latin1_General_100_CI_AS_KS_WS_SC. |
#5
| |||
| |||
|
|
Jeroen Mostert (jmostert (AT) xs4all (DOT) nl) writes: Even if the database is using a case-sensitive collation, stored procedure parameter names are not case sensitive within the stored procedure, at least not if the server collation is case-insensitive (at least in my tests; I had no opportunity to try it with a case-sensitive server collation). So the stored procedure is not at fault. Obviously the procedure is not a fault, as the error is in the application. But variables always follow the server collation. Consider this script: CREATE DATABASE CI COLLATE Latin1_General_CI_AS go USE CI go CREATE PROCEDURE sp AS DECLARE @i int = 1 DECLARE @I int = 2 go EXEC sp go CREATE PROCEDURE sp1 AS DECLARE @i int = 1 SELECT @I = 2 go EXEC sp2 gi USE tempdb go DROP DATABASE CI I get this output when I run it on my server which has Finnish_Swedish_CS_AS as the server collation: Msg 137, Level 15, State 1, Procedure sp1, Line 3 Must declare the scalar variable "@I". Msg 2812, Level 16, State 62, Line 1 Could not find stored procedure 'sp2'. That is, the first procedure compiles, the second fails to compile. This is a peculiar and to my knowledge undocumented thing (at least, it's |
|
A case-sensitive collation on your database is supremely evil. Alright, not *supremely* evil, but very awkward for most use cases. As this exercise shows, there is a use-case where case-sensitive collations are essential: development environments. In my opinion, you should always develop in a case-sensitive environment, exactly to avoid this sort of problems. I'm afraid I don't follow. You should develop on a system with a |
|
In SQL 2012, there is a new feature that evades this problem: contained databases. In a contained database, the collation for metadata is always the one and the same, Latin1_General_100_CI_AS_KS_WS_SC. That's pretty nifty. |
#6
| |||
| |||
|
|
CREATE PROCEDURE sp1 AS ^ DECLARE @i int = 1 SELECT @I = 2 go EXEC sp2 ^ This should be "1" |
|
gi ^^ Not the best spelling of "go". |
|
My system has the default collation. At the lest, I am unaware of having changed it. After correcting the errors noted above, I get: Msg 134, Level 15, State 1, Procedure sp, Line 3 The variable name '@I' has already been declared. Variable names must be unique within a query batch or stored procedure. Msg 2812, Level 16, State 62, Line 1 Could not find stored procedure 'sp'. |
#7
| |||
| |||
|
|
This is a peculiar and to my knowledge undocumented thing (at least, it's not documented in the places where I'd expect it to be documented). Seeing as how it openly breaks database encapsulation, I consider it a serious misfeature. |
|
I'm afraid I don't follow. You should develop on a system with a case-sensitive collation so you will run into the problems you will not have on production because you're smart enough not to use a case-sensitive collation there? |
|
I'd probably introduce *more* errors if my server had case-sensitive collation, as I'd have to remember to create all my databases with a case-insensitive collation (otherwise the behavior would be seriously different from production, with even data being case-sensitive). |
#8
| |||
| |||
|
|
Gene Wirchenko (genew (AT) ocis (DOT) net) writes: Erland: |
|
gi ^^ Not the best spelling of "go". How did that happen? I know that I ran into that error when I tested the repro, I corrected it. How did it end up in the news post? Did I inadverently press CTRL-Z before I copied? |
|
My system has the default collation. At the lest, I am unaware ^^^^ |
![]() |
| Thread Tools | |
| Display Modes | |
| |