SQL Server条件插入
我有一个包含零件供应商信息的表格 背景:此表是的联接SQL Server条件插入,sql,sql-server-2008,tsql,insert,Sql,Sql Server 2008,Tsql,Insert,我有一个包含零件供应商信息的表格 背景:此表是的联接 零件主记录,其中包含 零件号、零件名称和默认供应商 另一个表是供应商信息表,其中包含 供应商的零件号记录及其零件报价(本例中我遗漏了额外信息) 在此表中,默认供应商的部分零件为空。 对于这些记录,我想插入一个新记录作为占位符 i、 e.下文第3段 某些零件有默认供应商,但没有可能供应商的记录(带报价)。 对于这些记录,我还想插入一个新记录作为占位符。 i、 e.下文第1条 当前表 +-------+-----------+----
- 零件主记录,其中包含
- 零件号、零件名称和默认供应商李>
- 另一个表是供应商信息表,其中包含
- 供应商的零件号记录及其零件报价(本例中我遗漏了额外信息)
+-------+-----------+-------------------+-------------------+------------+------------+
|PART |PART NAME |Default Supplier |Possible Suppliers |Quote |InfoComplete|
+-------+-----------+-------------------+-------------------+------------+------------+
|#1 |Part 1 |Supplier 5 |Supplier 1 |25.0 |0 |
|#1 |Part 1 |Supplier 5 |Supplier 2 |20.5 |0 |
|#2 |Part 2 |Supplier 10 |Supplier 10 |10.4 |1 |
|#3 |Part 3 |NULL |Supplier 3 |9.5 |0 |
|#3 |Part 3 |NULL |Supplier 4 |11.5 |0 |
+-------+-----------+-------------------+-------------------+------------+------------+
所需输出(为清晰起见显示的空间)
据我所知,merge语句可能是一个解决方案,但我根本无法让它工作
编辑:
对不起,我在我的第一篇文章中应该说得更清楚一点,信息正在导出到,以便用户查看丢失的数据。
没有计划替换数据库中的空值
我只想操纵数据,让用户更清楚地理解数据
根据反馈,我正在寻找更好的方式向用户显示信息。考虑使用触发器
CREATE TRIGGER NULL_DEFAULTSUPP
AFTER INSERT ON TABLE-NAME
FOR EACH ROW BEGIN
WHERE NEW.Default Supplier IS NULL
BEGIN
INSERT INTO TABLE-NAME VALUES(NEW.PART, NEW.PART-NAME, "**MISSING**", ....);
END;
我决定不必等着听你解释为什么要用空值替换空值。我只能假设您希望这样做,因为您希望查询简单,并且在默认供应商为空时输出短语
**MISSING**
。有更好的方法以不重复的方式完成该任务,而不是将您的供应商外键(假设您有一个)转换为从不包含null的可为null的varchar字段
如果是这样的情况,我建议您使用视图访问此数据:
IF ( OBJECT_ID('dbo.vw_PartsSuppliers') IS NOT NULL )
DROP VIEW dbo.vw_PartsSuppliers
GO
CREATE VIEW dbo.vw_PartsSuppliers
AS
SELECT
p.PartId,
p.PartName,
ISNULL(s.SupplierName, '**MISSING**'),
ISNULL(s.Quote, 'NA'),
s.InfoComplete
FROM
dbo.Part p
LEFT JOIN dbo.Supplier s ON p.DefaultSupplierId = s.SupplierId
GO
此方法灵活且可重用,并将为您提供所需的格式。此外,一旦出现一个查询,您需要识别没有默认供应商的零件(您可能会这样做),您就不会受到性能影响,因为您没有搜索
**缺失**
魔术字符串,但改为NULL。在此场景中,SupplierId用作表dbo.Supplier的主键,Id主键用于表dbo.SupplierInfo,该表与外键DefSupplierId上的表dbo.Supplier关联
DECLARE @SupplierId TABLE(SupplierId int)
INSERT dbo.Supplier(Part, PartName, DefaultSupplier)
OUTPUT inserted.SupplierId INTO @SupplierId(SupplierId)
SELECT DISTINCT s.Part, s.PartName, ISNULL(s.DefaultSupplier, '**MISSING**')
FROM dbo.Supplier s LEFT JOIN dbo.SupplierInfo i ON s.SupplierId = i.DefSupplierId
WHERE s.DefaultSupplier IS NULL OR i.PossibleSuppliers IS NULL
INSERT dbo.SupplierInfo
SELECT SupplierId, '**MISSING**', 0, 0
FROm @SupplierId
下面是一个稍微简化的示例,说明如何使用合并来实现所需的输出。只有一个表
PartsApplicationInfo
包含有关零件和供应商的数据,如上例所示
;WITH trgtCTE AS
(
SELECT Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete FROM PartsSuppliersInfo
WHERE DefaultSupplier = '**MISSING**' OR [PossibleSuppliers] = '**MISSING**'
)
MERGE trgtCTE AS trgt
USING
(
SELECT DISTINCT Part, PartName, '**MISSING**' AS DefaultSupplier,'**MISSING**' AS PossibleSuppliers, NULL AS Quote, 0 AS InfoComplete FROM PartsSuppliersInfo
WHERE DefaultSupplier IS NULL
UNION
SELECT DISTINCT p.Part, PartName, DefaultSupplier,'**MISSING**' AS PossibleSuppliers, NULL AS Quote, 0 AS InfoComplete FROM PartsSuppliersInfo p
WHERE DefaultSupplier IS NOT NULL AND InfoComplete = 0
) src
ON src.part = trgt.part AND src.DefaultSupplier = trgt.DefaultSupplier AND src.PossibleSuppliers = trgt.PossibleSuppliers
WHEN NOT MATCHED BY TARGET THEN
INSERT (Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete)
VALUES (Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
MERGE
的目标部分是CTE,只有行具有**缺少**
关键字。第一次它是空的,但每次下一次运行语句时,它都会有上一次运行的结果
源部分是一个子查询,具有如何计算应存在哪些**缺失**
行的逻辑
最后两个部分删除不再需要的行(如果部分不再丢失),并插入新行。如果NULL是更有效和典型的数据排列方式,为什么要浪费额外的空间在这些记录中存储“**missing**”?此外,采用这种方法将降低搜索默认供应商为空的零件的效率。我无法从示例中看出第1部分(以及第3部分)如何从可能的供应商处丢失?谢谢您的帮助。我编辑了我最初的帖子来解释我的疯狂!
;WITH trgtCTE AS
(
SELECT Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete FROM PartsSuppliersInfo
WHERE DefaultSupplier = '**MISSING**' OR [PossibleSuppliers] = '**MISSING**'
)
MERGE trgtCTE AS trgt
USING
(
SELECT DISTINCT Part, PartName, '**MISSING**' AS DefaultSupplier,'**MISSING**' AS PossibleSuppliers, NULL AS Quote, 0 AS InfoComplete FROM PartsSuppliersInfo
WHERE DefaultSupplier IS NULL
UNION
SELECT DISTINCT p.Part, PartName, DefaultSupplier,'**MISSING**' AS PossibleSuppliers, NULL AS Quote, 0 AS InfoComplete FROM PartsSuppliersInfo p
WHERE DefaultSupplier IS NOT NULL AND InfoComplete = 0
) src
ON src.part = trgt.part AND src.DefaultSupplier = trgt.DefaultSupplier AND src.PossibleSuppliers = trgt.PossibleSuppliers
WHEN NOT MATCHED BY TARGET THEN
INSERT (Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete)
VALUES (Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;