12 sql sql-server
我的团队成员已经获得了一些奇怪的行为,可以在开发环境和系统测试环境MS SQL数据库中重新创建.
如果他直接运行此查询,则返回517行,这是正确的预期结果:
SELECT
p.package_id, la.CODE_KID
FROM package p with (nolock), Strength s with (nolock),
ProductCODE la with (nolock), CODE a with (nolock)
where p.Strength_ID = s.Strength_ID
and la.Product_ID = s.Product_ID
AND la.CODE_KID = a.CODE_ID
except
select p.package_ID, p.CODE_KID from package p
Run Code Online (Sandbox Code Playgroud)
但是,如果他在视图中放置相同的查询,则错误地返回311行 - 比直接运行查询时少206行.
如果我们为直接查询和视图查询运行查询分析器,我们会看到两个查询计划完全不同,但我们不明白为什么.
他还试图将查询转储到临时表中:
insert into MyDB.CODE_PACKAGE
SELECT
p.package_id, la.CODE_KID
FROM package p with (nolock), Strength s with (nolock),
ProductCODE la with (nolock), CODE a with (nolock)
where p.Strength_ID = s.Strength_ID
and la.Product_ID = s.Product_ID
AND la.CODE_KID = a.CODE_ID
except
select p.package_ID, p.CODE_KID from package p
Run Code Online (Sandbox Code Playgroud)
,正确创建一个包含517行的表.但是,如果他将相同的SQL放在存储过程中,则会错误地返回311行.
似乎一旦查询被封装在数据库对象中,它就会返回太少的行.
如上所述,他也在其他数据库系统上重新创建了错误.
什么想法会导致这种奇怪的行为?
他也尝试过以下方面但没有取得任何成功:
nolock更新
我不确定是否使用SSMS向导或模板来创建视图,但如果我选择"脚本视图为 - >创建到 - >新查询编辑器窗口",那么这是输出:
USE [TestUtv]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE view [MyDBviews].[CODE_PACKAGE]
as
SELECT
p.package_id, la.CODE_KID
FROM package p with (nolock), Strength s with (nolock),
ProductCODE la with (nolock), CODE a with (nolock)
where p.Strength_ID = s.Strength_ID
and la.Product_ID = s.Product_ID
AND la.CODE_KID = a.CODE_ID
except
select p.package_ID, p.CODE_KID from package p
GO
Run Code Online (Sandbox Code Playgroud)
这是使用的表之一,遗憾的是数据库非常庞大,有数百个表和视图,所以我不能在这里发布所有内容.
CREATE TABLE [dbo].[Package](
[Package_ID] [uniqueidentifier] NOT NULL,
[Multiple] [int] NULL,
[Multiple2] [int] NULL,
[OutProdnum] [varchar](6) NULL,
[OutProdnumDate] [datetime] NULL,
[zzzPackage_KID] [uniqueidentifier] NULL,
[Strength_ID] [uniqueidentifier] NULL,
[Indi] [varchar](4096) NULL,
[CreatedDate] [datetime] NULL,
[CreatedBy] [varchar](255) NULL,
[LastChangedDate] [datetime] NULL,
[LastChangedBy] [varchar](255) NULL,
[CODE_KID] [uniqueidentifier] NULL,
[MarkDate] [datetime] NULL,
[Amount] [int] NULL,
[KIPackage_ID] [uniqueidentifier] NULL,
[xyz] [bit] NULL,
[Ean] [varchar](255) NULL,
[D_ID] [uniqueidentifier] NULL,
[abc_ID] [uniqueidentifier] NULL,
[DDD] [decimal](18, 4) NULL,
[era_KID] [uniqueidentifier] NULL,
[uuu] [decimal](18, 4) NULL,
[ueer_KID] [uniqueidentifier] NULL,
[abcIdString] [varchar](4095) NULL,
[ExternalId] [varchar](255) NULL,
[Dpack_KID] [uniqueidentifier] NULL,
[tttpacks_KID] [uniqueidentifier] NULL,
CONSTRAINT [Package_PK] PRIMARY KEY CLUSTERED
(
[Package_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]
Run Code Online (Sandbox Code Playgroud)
使用 JOIN 语句尝试相同的查询。对于使用这种旧连接技术的查询,您可能会从不同的查询计划中得到不同的结果。
SELECT
p.package_id,
la.CODE_KID
FROM package p with (nolock)
INNER JOIN Strength s with (nolock)
ON p.Strength_ID = s.Strength_ID
INNER JOIN ProductCODE la with (nolock)
ON la.Product_ID = s.Product_ID
INNER JOIN CODE a with (nolock)
ON la.CODE_KID = a.CODE_ID
EXCEPT
SELECT
p.package_ID,
p.CODE_KID
FROM package p
Run Code Online (Sandbox Code Playgroud)