【发布时间】:2019-02-08 18:51:36
【问题描述】:
我有这 3 张桌子
- 公司
- 身份证
- 分公司
- 身份证
- 项目
- 身份证
- 库存号
公司可以有很多分公司,一个分公司可以有很多项目。
现在我要编写一个查询,该查询将根据条件插入或更新项目。
有些项目在公司只能出现一次,有些项目可以在每个分公司出现。
对我来说问题是那些只能在公司出现一次的问题。我想我基本上需要将所有这些表连接在一起并进行检查,但我不知道如何在“Merge Into Sp”中加入
我做了一个看起来像这样的表格类型
CREATE TYPE ItemTableType AS TABLE
(
BranchId INT,
CompanyId INT
Description nvarchar(Max),
StockNumber: INT
);
在我的代码中,我可以将 companyId 传递给我的表格类型
CREATE PROCEDURE dbo.Usp_upsert @Source ItemTableType readonly
AS
MERGE INTO items AS Target
using @Source AS Source
ON
// need to somehow look at the companyId so I can then find the right record reguardlesss of which branch it sits in.
Targert.CompanyId = source.CompanyId // can't do this just like this as Item doesn not have reference to company table.
Target.StockNumber = source.StockNumber
WHEN matched THEN
// update
WHEN NOT matched BY target THEN
// insert
编辑
样本数据
Company
Id Name
1 'A'
2 'B'
Branch
Id name CompanyId
1 'A.1' 1
2 'A.2' 1
3 'B.1' 2
4 'B.2' 3
Item
Id Name StockNumber BranchId
1 Wrench 12345 1
2 Wrench 12345 3
3 Hammer 484814 2
4 Hammer 85285825 4
现在将通过 C# 代码将批量数据发送到此 SP,看起来像这样
DataTable myTable = ...;
// Define the INSERT-SELECT statement.
string sqlInsert = "dbo.usp_InsertTvp"
// Configure the command and parameter.
SqlCommand mergeCommand = new SqlCommand(sqlInsert, connection);
mergeCommand.CommandType = CommandType.StoredProcedure;
SqlParameter tvpParam = mergeCommand.Parameters.AddWithValue("@Source", myTable);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.SourceTableType";
// Execute the command.
insertCommand.ExecuteNonQuery();
现在说什么时候导入记录并且数据看起来像这样
Wrench (Name), 12345 (StockNumber), 2 (BranchId..they are switching the branch of this item to another branch)
如果我只是发送这个,那么如果我使用 BranchId + Stocknumber,则不会更新任何内容并插入新记录,这会是错误的,因为现在 2 个分支具有相同的项目(基于 stockNumber)
如果我只使用 StockNumber,那么这 2 条记录将被更新。
1 Wrench 12345 1
2 Wrench 12345 3
这是错误的,因为这些记录来自 2 家不同的公司。因此我还需要使用 companyId,因此我还需要检查 companyId。
编辑(来自 cmets):
我想我必须做一些目标点。到目前为止,这是我想出的:
MERGE INTO Items AS Target
using @Source AS Source
ON Source.CompanyID=(
SELECT TOP 1 Companies.Id
FROM Branches
INNER JOIN Companies
ON Branches.CompanyId = Companies.Id
INNER JOIN InventoryItems
ON Branches.Id = Target.BranchId
where Companies.Id = Source.CompanyId
and StockNumber = Source.StockNumber
)
【问题讨论】:
标签: sql-server join stored-procedures sql-server-2017