我正在尝试对我们分支机构的暂存数据合并进行模块化。
目前,我每天每个分支机构(50 多个分支机构)从我们的系统供应商那里获得一个导出文件 (zip)。通过一系列 Azure 功能,我提取了 zip,它提供了一系列 tsv 文件,然后我将每个 tsv 文件上传到一个暂存表。对暂存数据进行必要的转换后,我需要将暂存数据合并到正确的表中。
我已经编写了单独的存储过程来处理每个表的合并。我知道一旦处理数据转换的函数将消息写入 Azure 队列以对此发出警报,就可以合并暂存表。然后最终函数使用此消息来触发特定的存储过程。
我遇到的问题是许多目标表都有外键。
例如,一个表 (TransferLine) 列出了分支传输的项目,这包括 TransferID 字段,它是 TransferHeader 表中传输的 ID。由于我设置了 FK,在这种情况下,TransferID 必须存在于 TransferHeader 表中,因此需要在 TransferLines 暂存表之前处理 TransferHeader 暂存表数据,因为新的 TransferId 不会存在。
TransferHeader 表(无关列被忽略)
TransferId varchar(15) PK
TransferType int NOT NULL
...
TransferLine 表(忽略无关列) 您可以看到 TransferId 是包含 ProductId 的复合键的一部分。
TransferId varchar(15) PK FK
ProductId varchar(35) PK
ProductCode varchar(20) NOT NULL
TransferQuantity int NOT NULL
...
是否有正确的方法来决定是立即运行还是延迟运行存储过程?
到目前为止,这个设置是否是一个可行的解决方案,还是我以错误的方式解决这个问题?据我所知,SQL Server 内部的延迟和等待是基于计时器或命令的。由于我无法保证是否首先存储了 TransferHeader 或 TransferLine 暂存数据,因此我不认为直接 SQL Server 解决方案最适合我的情况。
我知道我可以有一个触发器,它可以在处理所有表时触发,然后按所需顺序运行每个存储过程。我想要将其模块化的原因是将每个表作为自己的表来处理。在极端情况下,分支机构可能会在一天内不创建新的转账,但可能会编辑现有的转账。这意味着那天不会有 TransferHeader tsv 文件,但会有一个 TransferLine 文件。这样我就不能简单地等待 TransferHeader 表进行处理,因为它会在那天被跳过。
最后,我要补充一点,我可以在获得数据后进行转换,但我需要从系统供应商提供的数据开始。
概念化您的设置有点困难。查看流程和存储过程的代码可能会有所帮助。
但这听起来像你的问题是你的标题和行表的进程可以并行运行,基本上首先更新行表的机会。如果是这样,那么您基本上需要删除流程的并行部分,并在标头流程完成后按顺序显式更新行。
一种方法是为每组相关表设置一个过程。在您的示例中,依赖链中只有两个表,这很简单。如果有更多的表与其他表的混合使用更多的外键,它可能会使这更复杂。
因此,例如,我有一个
ProcessTranfers
过程先处理TransferHeader
表,然后TransferLines
再处理表,因为这是外键依赖关系的顺序。ProcessTransfers
在这种情况下,使用我前面提到的方法,表过程的第一部分不会有任何工作TransferHeader
,它会立即只做表所需的工作TransferLine
。闻起来有点像是走错了路。外键的目的是强制执行父记录存在的约束,以便子记录存在(简化定义)。如果您当前的流程不能保证事件的顺序,那么它可能会违反该外键约束。您的选择是要么设计一个流程来保证事件的正确顺序,要么删除外键约束并在一段时间内间歇性地存在没有父行的子行的风险。