带索引视图的sql合并语句

ozxc1zmp  于 2021-08-13  发布在  Java
关注(0)|答案(1)|浏览(315)

我正在使用sql server 2016并尝试创建 MERGE 语句,如果不存在则插入新记录,如果存在则获取记录的id。
这是正常工作,但有意外的副作用,导致索引视图被更新,即使没有数据被更新时,我运行此多次。
这是预期的行为还是我只是做错了什么?
直观地说,我想我会认为,因为合并找到了一个匹配项,然后只更新一个局部变量,所以对索引视图的任何更改都不会显示在执行计划中。

CREATE TABLE dbo.Customer
(
    CustomerId INT IDENTITY(100,1) PRIMARY KEY NOT NULL,
    CustomerName VARCHAR(100) NOT NULL
)
GO

CREATE VIEW dbo.Customer_v
WITH SCHEMABINDING
AS
    SELECT CustomerId, CustomerName 
    FROM dbo.Customer
GO

CREATE UNIQUE CLUSTERED INDEX [CL_IX_Customer_v]
ON dbo.Customer_v(CustomerId ASC);
GO

DECLARE @CustomerId AS INT
DECLARE @CustomerName AS VARCHAR(100) = 'Mike Smith'
DECLARE @WasCustomerCreated AS BIT = 0
DECLARE @SummaryOfChanges TABLE(Change VARCHAR(20));

MERGE INTO dbo.Customer AS Target
USING (VALUES (@CustomerName)) AS Source (CustomerName) ON (Target.CustomerName = Source.CustomerName)

WHEN MATCHED THEN 
    UPDATE SET @CustomerId = Target.CustomerId

WHEN NOT MATCHED THEN 
    INSERT (CustomerName) VALUES (@CustomerName)

OUTPUT $action INTO @SummaryOfChanges;

IF EXISTS(SELECT * FROM @SummaryOfChanges WHERE Change = 'Insert')
BEGIN
    SET @WasCustomerCreated = 1
    SET @CustomerId = SCOPE_IDENTITY()
END

SELECT @CustomerId AS CustomerId, @WasCustomerCreated AS WasCustomerCreated
zi8p0yeb

zi8p0yeb1#

您可以将“and@customerid<>target.customerid”添加到merge语句中:

MERGE INTO dbo.Customer AS Target
USING (VALUES(@CustomerName)) AS Source (CustomerName)
ON (Target.CustomerName = Source.CustomerName)
WHEN MATCHED AND @CustomerId <> Target.CustomerId THEN UPDATE SET @CustomerId = Target.CustomerId
WHEN NOT MATCHED THEN INSERT (CustomerName) VALUES (@CustomerName)
OUTPUT $action INTO @SummaryOfChanges;

相关问题