gpt4 book ai didi

SQL Server,where 子句与不同类型的比较和默认转换行为

转载 作者:行者123 更新时间:2023-12-02 23:51:50 24 4
gpt4 key购买 nike

对...今天这个问题让我困惑了一段时间,所以也许你们中的一位 SQL Server 聪明人可以阐明这一行为。

我们有一个表电话。其中,电话号码存储为 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

第一个选择(标记为#1)将起作用第二个选择(标记为#2)将起作用,但会立即给出错误第三个选择(标记为#3)不返回任何内容。

返回的错误是

Error converting data type nvarchar to bigint.

现在这看起来完全是疯狂的行为。我认为会发生的是

  1. SQL 在 WHERE 子句中实现比较 2 种不同的数据类型
  2. 它会尝试将@variable转换为列的数据类型
  3. 如果失败,抛出一个错误,它可以工作,太棒了!!!

实际发生的情况是

  1. SQL 在 WHERE 子句中实现比较 2 种不同的数据类型
  2. 它会逐行将列中的值转换为 @variable 的数据类型
  3. 对于每次成功的转换,它都会进行比较,并返回该行。
  4. 如果它遇到列中无法转换的值,它会进行轰炸,返回迄今为止找到的任何数据,并且不会继续遍历表。

任何人都可以澄清此逻辑背后的推理是什么,以及 SQL Server 在决定比较/转换内容时是否为数据类型提供任何特定的优先顺序

注意。我在 SQL 2005 中进行了此测试,但它在 SQL2K 中也是可复制的行为。

最佳答案

数据类型优先级定义明确 - http://msdn.microsoft.com/en-us/library/ms190309.aspx

编辑-澄清一下,sql并不总是将列类型转换为参数类型。它只是遵循我给出的链接中的类型优先级。这可能意味着参数会转换为列类型(如果类型优先级指定的话)。

关于SQL Server,where 子句与不同类型的比较和默认转换行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/831150/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com