如何在无连接条件下实现T-SQL记录的一对一匹配?
解决SQL中INSERT OUTPUT无法获取源表列及一对一配对的问题
你的问题核心在于INSERT语句的OUTPUT子句只能访问插入后生成的inserted对象列,无法直接引用SELECT子句里的源表列,所以没法直接把cba.Id和新生成的GlobalId一起存入临时表。另外,你之前用CROSS JOIN和ROW_NUMBER没成功,是因为没建立正确的关联关系,导致无法一对一配对。
正确的解决方案:使用MERGE语句代替INSERT
MERGE语句的优势在于,它能同时访问**源表(SOURCE)和目标插入的表(INSERTED)**的列,完美解决你需要同时获取新生成Id和源表Id的需求。下面是修改后的完整代码:
DECLARE @SignatureGlobalIdsTbl table (ID int, CompanyBankAccountId int); -- 用MERGE代替INSERT,实现同时获取新GlobalId和源表的CompanyBankAccountId MERGE INTO GlobalIds AS Target USING ( SELECT cba.CompanyBankAccountId, @DocumentsGlobalTypeKey AS TypeId FROM CompanyBankAccounts cba INNER JOIN Companies c ON c.CompanyId = cba.CompanyId WHERE SignatureDocumentId IS NULL AND (SignatureFile IS NOT NULL AND SignatureFile != '') ) AS Source (CompanyBankAccountId, TypeId) ON 1 = 0 -- 永远不匹配,确保所有源行都被插入 WHEN NOT MATCHED THEN INSERT (TypeId) VALUES (Source.TypeId) OUTPUT Inserted.Id, Source.CompanyBankAccountId INTO @SignatureGlobalIdsTbl (ID, CompanyBankAccountId); -- 现在可以通过CompanyBankAccountId关联临时表,一对一获取对应的GlobalId INSERT INTO Documents (DocumentPath, DocumentType, DocumentIsExternal, OwnerGlobalId, OwnerGlobalTypeID, DocumentName, Extension, GlobalId) SELECT cba.SignatureFile, @SignatureDocumentTypeKey, 1, c.GlobalId AS CompanyGlobalId, @OwnerGlobalTypeKey, [dbo].[fnGetFileNameWithoutExtension](cba.SignatureFile), [dbo].[fnGetFileExtension](cba.SignatureFile), s.ID AS documentGlobalId FROM CompanyBankAccounts cba INNER JOIN Companies c ON c.CompanyId = cba.CompanyId INNER JOIN @SignatureGlobalIdsTbl s ON s.CompanyBankAccountId = cba.CompanyBankAccountId WHERE cba.SignatureDocumentId IS NULL AND (cba.SignatureFile IS NOT NULL AND cba.SignatureFile != '');
关键说明:
- MERGE的关联条件:
ON 1 = 0确保源表的每一行都不会和目标表(GlobalIds)匹配,所以所有源行都会执行INSERT操作,和你原来的INSERT逻辑一致。 - OUTPUT子句:这里可以同时获取
Inserted.Id(新生成的GlobalId)和Source.CompanyBankAccountId(源表的银行账户Id),存入临时表后就建立了一对一的映射关系。 - 后续关联:插入Documents时,直接用
CompanyBankAccountId关联临时表,避免了笛卡尔积,保证每一行源数据对应唯一的新GlobalId。
如果你坚持想用ROW_NUMBER的方法,也可以给源表和插入的GlobalIds都生成行号,然后通过行号关联,但MERGE的方法更简洁高效,是这类场景的标准解决方案。
内容的提问来源于stack exchange,提问作者johnny 5
相关产品推荐
相关产品推荐

