惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
爱范儿
爱范儿
D
Docker
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
D
DataBreaches.Net
月光博客
月光博客
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
Visual Studio Blog
MyScale Blog
MyScale Blog
B
Blog
阮一峰的网络日志
阮一峰的网络日志
L
LangChain Blog
Recent Announcements
Recent Announcements
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学

博客园 - 狂笑人生

SQL SERVER 2008 开发系列(十五) SQL SERVER 2008 开发系列(十四) SQL SERVER 2008 开发系列(十三) SQL SERVER 2008 开发系列(十二) SQL SERVER 2008 开发系列(十) SQL SERVER 2008 开发系列(十一) SQL SERVER 2008 开发系列(九) SQL SERVER 2008 开发系列(七) SQL SERVER 2008 开发系列(五) SQL SERVER 2008 开发系列(六) SQL SERVER 2008 开发系列(四) SQL SERVER 2008 开发系列(三) SQL SERVER 2008 开发系列(二) SQL SERVER 2008 开发系列(一)B SQL SERVER 2008 开发系列(一) 浅析逻辑数据映射[转载] 浅析实时ETL的架构选择[转载] 数据库性能优化 数据挖掘技术
SQL SERVER 2008 开发系列(八)
狂笑人生 · 2008-09-16 · via 博客园 - 狂笑人生

TSQL-Merge语句(新特点)

/**********************************************************
MERGE,这种语法可以融合UPDATE、DELETE和INSERT。
特别适合于将交易型的记录集合并到快照性的结果集中去。
非常具有代表性的应用场景就是库存管理,库存管理应用(俗称进销存)中
经常需要获得某个时间点上的库存,也称为库存结余。
**********************************************************/

--创建测试表
USE Blog
GO

--创建库存快照表
--Inventory-存货清单
CREATE TABLE Inventory_Snapshot
(
    ProductID    int PRIMARY KEY NOT NULL,--产品
    Quantity    int NOT NULL --数量
)
GO

--创建库存操作表
CREATE TABLE Inventory_Operation
(
    OperationID        int PRIMARY KEY    IDENTITY(1,1), --操作ID
    OperationDate    datetime, --操作时间
    OperationType    int,    --1:入仓; 2:出仓;
    ProductID        int, --产品
    Quantity        int  --数量
)
GO

--创建存储过程用于新的库存操作
CREATE PROCEDURE sp_Inventory_Operation
    @productID int,--产品ID
    @operationDate datetime,--操作时间
    @operationType int, --1:入仓; 2:出仓;
    @quantity    int --数量
AS
INSERT INTO Inventory_Operation
    (OperationDate, OperationType, ProductID, Quantity)
VALUES
    (@operationDate, @operationType, @productID, @quantity)
GO

--创建存储过程用于库存快照计算
CREATE PROCEDURE sp_Inventory_Snapshot_Process
    @processDate datetime --时间
AS
MERGE Inventory_Snapshot AS invs --为快照表取别名
USING
(
    SELECT ProductID, Sum(ABSQuantity) AS SubTotal
    FROM (
            SELECT ProductID, Quantity  *
       CASE OperationType --1:入仓; 2:出仓;
                    WHEN 1 THEN 1
                    WHEN 2 THEN -1
                    ELSE 0
                END AS ABSQuantity  --如果是入库,则是正数,如果是出库,则是负数
            FROM Inventory_Operation
            WHERE OperationDate = @processDate
        ) AggInvo       
    GROUP BY AggInvo.ProductID
) AS invo(ProductID, SubTotal) --库存操作表
ON (invs.ProductID = invo.ProductID) --将库存表与快照关联起来
WHEN MATCHED --更新
    AND invs.Quantity <> invo.SubTotal
    AND invs.Quantity <> invo.SubTotal * -1
THEN
    UPDATE SET invs.Quantity = invs.Quantity + invo.SubTotal
WHEN MATCHED --删除
    AND invs.Quantity = invo.SubTotal * -1
THEN DELETE
WHEN NOT MATCHED BY TARGET --新增
THEN INSERT VALUES (invo.ProductID, invo.SubTotal);
GO
--清空库存快照表
DELETE FROM dbo.Inventory_Snapshot

--测试应用程序逻辑,先入库操作,填充库存
EXEC sp_Inventory_Operation 1000, '2008-9-7', 1, 500
EXEC sp_Inventory_Operation 1001, '2008-9-7', 1, 300
EXEC sp_Inventory_Operation 1002, '2008-9-7', 1, 250

--测试当前的库存快照
EXEC sp_Inventory_Snapshot_Process '2008-9-7'

SELECT * FROM Inventory_Snapshot
GO
--第二次测试,1001 产品出库 200,新入库1003产品数据300; 1000产品出库200
EXEC sp_Inventory_Operation 1001, '2008-9-8', 2, 200
EXEC sp_Inventory_Operation 1003, '2008-9-8', 1, 300
EXEC sp_Inventory_Operation 1000, '2008-9-8', 2, 200

--查看当前库存
EXEC sp_Inventory_Snapshot_Process '2008-9-8'

SELECT * FROM Inventory_Snapshot
GO
--第三次测试,全部出库操作,
EXEC sp_Inventory_Operation 1000, '2008-9-9', 2, 200
EXEC sp_Inventory_Operation 1002, '2008-9-9', 2, 250
EXEC sp_Inventory_Operation 1003, '2008-9-9', 2, 300

--查看当前库存
EXEC sp_Inventory_Snapshot_Process '2008-9-9'

SELECT * FROM Inventory_Snapshot

/**********************************************************
总结
**********************************************************/

在 SQL Server 2008 中,您可以使用 MERGE 语句在一条语句中执行插入、更新或删除操作。MERGE 语句允许您将数据源与目标表或视图联接,然后根据该联接的结果对目标对象执行多项操作。例如,您可以使用 MERGE 语句执行以下操作:

· 使用一个语句有条件地在单个目标表中插入或更新行。
如果目标表中存在相应行,则更新一个或多个列;否则,会将数据插入新行。

· 同步两个表。
根据与源数据的差别在目标表中插入、更新或删除行。

MERGE 语法包括五个主要子句:

· MERGE 子句用于指定作为插入、更新或删除操作目标的表或视图。

· USING 子句用于指定要与目标联接的数据源。

· ON 子句用于指定决定目标与源的匹配位置的联接条件。

· WHEN 子句用于根据 ON 子句的结果指定要执行的操作。

· OUTPUT 子句针对更新、插入或删除的目标对象中的每一行返回一行。