我有这3张桌子
公司可以有很多分支,而一个分支可以有很多项目。
现在,我必须编写一个查询,该查询将根据条件插入或更新项目。
某些项目只能在公司中出现一次,而某些项目可以在每个分支机构中出现。
对我来说,问题是只能在公司中出现一次的问题。我想我基本上需要将所有这些表连接在一起并进行检查,但是我不知道如何在“合并到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。
编辑(根据评论):
我认为我必须做一些目标点。到目前为止,这是我想出的:
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
)
答案 0 :(得分:1)
对于我来说,您需要做什么的描述太模糊了,因此您可以简单地使用JOIN作为源进行查询。我喜欢将其放在CTE中,使其看起来像这样:
WITH cte AS (SELECT query with JOINS)
MERGE INTO items AS Target
using cte AS Source
ON
编辑:要同时在目标(items
)上执行JOIN操作,您需要在ON条件下执行此操作:
WITH cte AS (SELECT query with JOINS)
MERGE INTO items AS Target
using cte AS Source
ON Source.CompanyID=(
SELECT TOP 1 CompanyId
FROM TableWithCompanyId
JOIN Target
ON JoinCondition=true
)...
我知道您的表涉及从物品到公司的两个表格,但是上面的示例向您展示了我认为您所缺少的技术。
编辑2,基于最新尝试:
尝试一下:
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
WHERE Branches.Id = Target.BranchId
)
and Target.StockNumber = Source.StockNumber