SSIS 错误消息:违反 PRIMARY KEY 约束

SSIS error message: Violation of PRIMARY KEY constraint

对于大学小组项目,我们正在使用 SQL 服务器管理和 Visual Studio 构建数据仓库。我们目前在暂存区,想要用数据填充 tables。它适用于我们的维度 tables,但它根本不适用于我们的事实 table 销售额。我们已经尝试了几种不同的选择,现在有两个最终选择,两者都应该有效。第一个选项可以在没有错误消息的情况下执行,但在“Merge Join”之后行停止转发。

使用第二个选项,我们在 OLE DB 目标 see image 中收到一条错误消息,如下所示:

[OLE DB Destination [115]] Error: SSIS Error Code DTS_E_OLEDBERROR. > An OLE DB error has occurred. Error code: 0x80004005.
An OLE DB record is available.
Source: "Microsoft SQL Server Native Client 11.0"
Hresult: 0x80004005
Description: "Violation of PRIMARY KEY constraint 'pk_Fact_Sales'. Cannot insert duplicate key in object 'dbo.Stg_Fact_Sales'. The duplicate key value is (2021-12-31, 017692475c1c954ff597feda05131d73, 3c7c4a49ec3c6550809089c6a2ca9370, a08ac24c7188aae96f09570ffde66b40, 66188).".

无论哪种方式,事实 table 在 SQL 上都是空的。

为了更好地理解和洞察,我们为您提供了我们的 SQL 脚本、平面文件以及 visual studio 数据流:Download files

如果有人能帮助找出我们的问题所在,我们将非常高兴!

非常感谢,祝一切顺利!


@Jayvee:再次感谢您的帮助!我们尝试按照您向我们建议的方法进行操作,它对我们也很有效!

然而,我们注意到价格之和+运费价值之和与payment_value不同,而且数值也与csv文件不同。这就是为什么我们尝试在排序 1 中额外选中“删除具有重复排序值的行”框。最终我们没有得到 117.216 行,而是得到了 102.727 行。然而,所有值之间仍然存在差异。为了更好地概述和理解,请参考下图:.

您知道为什么会发生这种情况或有解决此问题的方法吗?

此外,我们尝试推进评论事实 table。在此 table 中,我们想显示每个客户唯一 ID 的平均分数(针对订单),同时考虑到不同的日期。换句话说,一个客户可以在同一天进行多个评论,所以我们想对这些情况进行平均。如果客户在不同的日期进行了评论,我们不想在计算平均值时包含此信息。您能否帮助我们如何使用 visual studio 执行此操作?我们尝试使用聚合函数,但没有成功。你也可以在这里帮忙吗? (我们不关心与订单的关系,我们只想知道同一客户在同一天的平均评分。)

感谢您的宝贵时间和帮助!

问题在于 order_purchase_timestamp 在连接管理器中默认为错误的格式:

当读取平面文件任务只留下下游时间时,您可以启用数据查看器来查看它:

当这些字段在数据转换转换的派生列中转换为 purchase_day 时,它假定为当前日期,因此是您看到的今天日期,并且还会生成重复键。

您可能需要在连接管理器和所有转换中将数据类型更改为 db_dbtimestamp。此外,此问题也会发生在其他日期

有关 SSIS 和 SQL 服务器数据类型的更多信息:

https://docs.microsoft.com/en-us/sql/integration-services/data-flow/integration-services-data-types?view=sql-server-ver15

实际上有一些交易会创建重复键:

实际销量PK如下:

FK_Date ASC,  
FK_Product ASC,
FK_Sellers ASC,
FK_Customer_unique ASC,
FK_Payment ASC


FK_Date comes from orders file
FK_Product, FK_Sellers and FK_Customer_unique come from order_item file 
FK Payment comes from payment file

现在,如果我们检查创建 PK 副本的 product_id 文件 (cb07b3df7c64648bbeceb85cacd464c9)

在order_items中:

如您所见 2,具有相同 product_id、seller_id 和 order_id

的项目

在订单中:

付款:

因此,当来自 order_item 的两条记录与订单和付款文件合并时(使用 order_id 作为连接键),您最终会得到两条具有相同

的记录

FK_product (cb07b3df7c64648bbeceb85cacd464c9) FK_date (23-01-2017) FK_seller (62c50c1af4dfdc4149d25c5222043d39) FK_customer_unique (8a0793d04e0f4be13434516ee7037104) FK_payment (38321)

所以这就是为什么您需要向事实 table 添加一些内容以使其唯一(例如 order_item_id) 要么 通过在订单项目的排序转换中删除具有相同排序值的记录来忽略重复项 要么 order_items 组 order_id 总运费价值

这三个解决方案中的哪一个将取决于问题的规则(即运费的含义,是在物品之间划分还是只是重复?)

希望这有助于澄清问题

建议的解决方案

实际销售额table:

CREATE TABLE Stg_Fact_Sales (
FK_Date DATE ,
FK_Product NVARCHAR(50) ,
FK_Sellers NVARCHAR(50),
FK_Customer_unique NVARCHAR(50) ,
FK_Payment INT ,
Delays INT NULL,
Price DECIMAL(18, 2) NOT NULL,
Freight_value DECIMAL(18, 2) NOT NULL,
Payment_value DECIMAL (18,2) NOT NULL,
Order_status NVARCHAR(50) NOT NULL,
Order_id NVARCHAR(50) NOT NULL,
Order_item_id NVARCHAR(50) NOT NULL,
CONSTRAINT pk_Fact_Sales PRIMARY KEY (
Order_id ASC,
Order_item_id ASC,
FK_Payment ASC
)
);

如您所见,我在table中添加了order_id和order_item_id,并将这两列加上付款编号,作为复合PK。

现在包需要反映这些变化。

排序 1 现在包括 order_item_id

也执行 Merge Join

并合并连接 1

最后确保将这两个新字段映射到 OLE DB 目标中的相应列:

结果: 所有数据加载无问题: