Eoi*_*ell 5 sql sql-server types casting
对吧......这个让我困惑了一会儿,所以也许你们其中一个SQL Server明亮的火花可以揭示这种行为.
我们有一张桌子Phones.在其中,电话号码存储为nvarchars,它包含国际格式的数字,仅以数字格式...所以美国号码+1-(212)-999-9999存储为12129999999
由于超出原因,我有人编写了一个SPROC,将电话号码作为bigint,没有投射,做了一个简单的where子句=比较,并且这非常好,直到一些垃圾数据进入nvarchar列导致它破裂的桌子.请考虑以下测试脚本.
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 --Select #1
Print 'Inserting Junk Data'
INSERT INTO Phones (Mobile) VALUES ('JUNK DATA')
INSERT INTO Phones (Mobile) VALUES ('12129999999')
Print 'Selecting From Table Containing Junk'
SELECT * FROM Phones WHERE Mobile = @biMobile_1 -- Select #2
SELECT * FROM Phones WHERE Mobile = @biMobile_2 -- Select #3
Run Code Online (Sandbox Code Playgroud)
第一个选择(标记为#1)将起作用第二个选择(标记为#2)将起作用但在第三个选择(标记为#3)后不会立即返回错误.
返回的错误是
Error converting data type nvarchar to bigint.
Run Code Online (Sandbox Code Playgroud)
现在这似乎完全是疯子的行为.我认为会发生什么
WHERE子句中比较2种不同的数据类型实际上似乎正在发生的是
WHERE子句中比较2种不同的数据类型任何人都可以澄清这个逻辑背后的原因是什么,以及SQL Server在决定比较/转换时给予数据类型的任何特定优先顺序
注意.我在SQL 2005中进行了这个测试,但它在SQL2K中也是可复制的行为.
数据类型优先级定义明确 - http://msdn.microsoft.com/en-us/library/ms190309.aspx
编辑-澄清一下,sql并不总是将列类型转换为参数类型。它只是遵循我给出的链接中的类型优先级。这可能意味着参数将转换为列类型(如果类型优先级指定的话)。
| 归档时间: |
|
| 查看次数: |
5764 次 |
| 最近记录: |