That's right ... this question has puzzled me a long time ago, so perhaps one of you bright SQL Server sparks can shed light on this behavior.
We have a Phones table. In it, phone numbers are stored as nvarchars and contain numbers in the international format, only in digital format ... therefore, the number in the USA +1-(212)-999-9999 stored as 12129999999
For reasons that are beyond the scope, someone wrote me SPROC, which took the phone number as bigint, did not cast, made simple, where clause = comparison, and this worked perfectly fine until some unwanted data got into the column nvarchar to the table that caused it to break. Consider the following test script.
IF EXISTS (SELECT * FROM sys.tables WHERE name = 'Phones') BEGIN DROP TABLE Phones END GO CREATE TABLE [dbo].[Phones] ( [ID] [int] IDENTITY(1,1) NOT NULL, [Mobile] [nvarchar](50) NOT NULL, CONSTRAINT [PK_Phones] PRIMARY KEY CLUSTERED ( [ID] ASC ) WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY] ) ON [PRIMARY] GO DECLARE @biMobile_1 bigint DECLARE @biMobile_2 bigint SET @biMobile_1 = 12121111111 SET @biMobile_2 = 12129999999 Print 'Inserting Phone Number' INSERT INTO Phones (Mobile) VALUES ('12121111111') Print 'Selecting Phone Number' SELECT * FROM Phones WHERE Mobile = @biMobile_1
The first choice (marked # 1) will work. The second choice (marked # 2) will work, but will give an error immediately after the third option (marked # 3) does not return anything.
Error returned:
Error converting data type nvarchar to bigint.
Now this is similar to the behavior of bonkers. What I thought would be
- SQL implements a comparison of two different data types in a
WHERE - It will try to convert @variable to column data type
- If it fails, throw an error, it will work, BIG !!!
What really happens is
- SQL implements a comparison of two different data types in a
WHERE - In row by row, it converts the value in the column to the @variable data type
- For each successful conversion, it performs a comparison and returns this string.
- If it falls into a value in a column that it cannot convert, it bombes, returns all the data that it has found so far, and does not continue through the table.
Can someone clarify what is behind this logic, and if there is any special order of priority that SQL Server provides to data types when it decides what to compare / distinguish
Note. I tested this test in SQL 2005, but it also reproduces the behavior in SQL2K.