-1

免责声明:我不是 SQL 专家。我试图在将记录插入父表之前将它们插入子表。(说完我开始怀疑这是否是一个好主意。)父表记录持有对子表记录的引用,并且所述引用不能为空。这需要我先插入子表,然后在辅助插入期间链接到父表。

无论如何,出于某种原因,此代码会在 IdentificationingData(子)表中随机生成孤立记录,例如,它们在 FraudScore(父)表中没有条目,即使它们应该这样做。

这就是我感到困惑的原因。为了解决这个问题,我开始将@tempFraudScore 表的内容转储到一个物理审计表中,这样我就可以准确地看到数据转换过程中发生了什么。当我将以下插入 FraudScore 的代码从 @tempFraudScore 切换到从审计表中插入时,所有子记录都成功创建了父记录。这对我来说毫无意义。

insert into IdentifyingData (EntryDateTime, IdentifyingDataTypeId, Value, Source)
select distinct GETDATE(), tfs.IdentifyingDataTypeId, tfs.Value, 'SSIS'
from @tempFraudScore tfs
where not exists (
    select id.IdentifyingDataTypeId, id.Value
    from IdentifyingData id
    where tfs.IdentifyingDataTypeId = id.IdentifyingDataTypeId
        and tfs.Value = id.Value
);

update tfs
set tfs.IdentifyingDataId = id.Id
from @tempFraudScore tfs
    inner join IdentifyingData id on
        tfs.Value = id.Value and
        tfs.IdentifyingDataTypeId = id.IdentifyingDataTypeId;

insert into FraudScore (EntryDateTime, FraudCriteriaId, AccountId, IdentifyingDataId, Score, Source)
select distinct
    GETDATE() EntryDateTime,
    tfs.FraudCriteriaId,
    tfs.AccountId,
    tfs.IdentifyingDataId,
    tfs.Score,
    'SSIS'
from @tempFraudScore tfs
    inner join FraudCriteria fc on
        tfs.FraudCriteriaId = fc.Id
            and fc.UniqueEntryPeriod = 0
where not exists (
    select fs.AccountId, fs.FraudCriteriaId, fs.IdentifyingDataId
    from FraudScore fs
    where tfs.AccountId = fs.AccountId
        and tfs.FraudCriteriaId = fs.FraudCriteriaId
        and tfs.IdentifyingDataId = fs.IdentifyingDataId
);

@tempFraudScore 预先填充了所有必要的字段,除了 IdentificationDataId;必须首先插入到 IdentificationData 中,然后使用创建的 ID 更新变量表来创建它。下面是变量表的结构:

declare @tempFraudScore table(
    FraudCriteriaId int,
    AccountId bigint,
    IdentifyingDataId bigint,
    IdentifyingDataTypeId smallint,
    Value varchar(100),
    Score int
);

有人可以告诉我是什么导致了这些孤立的识别数据记录吗?我是否应该重新考虑这两个表之间的关系是如何构建的?我正在尝试做一些事情,以便一旦将某个标识数据记录放入系统中,它就不会被重复;它只会被新创建的 FraudScore 记录引用。

Edit Attached 是来自审计表的屏幕截图,它显示了单个值的数据转换进度(这些记录的值列是相同的值;为了隐私起见,我将其模糊化)。请注意,尽管出现“Post-FraudScore Insert”消息,但相关记录从未真正插入到 FraudScore 表中。

在此处输入图像描述

Edit2 (2/6/2018):我已将以下代码添加到存储过程中以尝试解决此问题。我有一个值 (99999) 出现在 _Audit 表的 Value 列中,但没有出现在第二个表的 Value 列中,尽管代码只是将所有数据从同一源转储到这两个表中!我不确定它是否重要,但这个存储过程是从一个 SSIS 包的执行 SQL 任务中启动的,其 IsolationLevel 为“Serializable”。也就是说,我没有在代码中的任何地方明确使用事务,并且该执行 SQL 任务的 TransactionOption 设置为“支持”。我不知道这是否与这个问题有关。

insert into FraudScoreIdentifyingData_Audit
select 'Post-IdentifyingData Update', GETDATE(), FraudCriteriaId, AccountId, IdentifyingDataId, IdentifyingDataTypeId, Value, Score
from @tempFraudScore;

insert into FraudScoreIdentifyingData
select GETDATE(), FraudCriteriaId, AccountId, IdentifyingDataId, IdentifyingDataTypeId, Value, Score, 1
from @tempFraudScore;

这是两个表的模式:

在此处输入图像描述

4

2 回答 2

0

不能说是什么导致了问题。

Parent Table=FraudScore

Child Table=IdentifyingData

它们是如何相关的?首先你插入记录FraudScore然后使用输出子句如果你有多个插入,插入记录IdentifyingData

OUTPUT clause但是,即使问题因此没有解决,这是使用的理想情况。

    --data type similar to IdentifyingData
declare @tbl table(Id int,Value int,IdentifyingDataTypeId int)
declare @CurrentDateTime datetime=GETDATE()

begin try
begin transaction

insert into IdentifyingData (EntryDateTime, IdentifyingDataTypeId
, Value, Source)
OUTPUT INSERTED.Id, INSERTED.Value, INSERTED.IdentifyingDataTypeId  
        INTO @tbl  
select distinct @CurrentDateTime, tfs.IdentifyingDataTypeId
, tfs.Value, 'SSIS'
from @tempFraudScore tfs
where not exists (
    select id.IdentifyingDataTypeId, id.Value
    from IdentifyingData id
    where tfs.IdentifyingDataTypeId = id.IdentifyingDataTypeId
        and tfs.Value = id.Value
);


update tfs
set tfs.IdentifyingDataId = id.Id
from @tempFraudScore tfs
    inner join @tbl id on
        tfs.Value = id.Value and
        tfs.IdentifyingDataTypeId = id.IdentifyingDataTypeId;

insert into FraudScore (EntryDateTime, FraudCriteriaId, AccountId, 
IdentifyingDataId, Score, Source)
select distinct
    @CurrentDateTime EntryDateTime,
    tfs.FraudCriteriaId,
    tfs.AccountId,
    tfs.IdentifyingDataId,
    tfs.Score,
    'SSIS'
from @tempFraudScore tfs
    inner join FraudCriteria fc on
        tfs.FraudCriteriaId = fc.Id
            and fc.UniqueEntryPeriod = 0
where not exists (
    select fs.AccountId, fs.FraudCriteriaId, fs.IdentifyingDataId
    from FraudScore fs
    where tfs.AccountId = fs.AccountId
        and tfs.FraudCriteriaId = fs.FraudCriteriaId
        and tfs.IdentifyingDataId = fs.IdentifyingDataId
);
COMMIT
end TRY
begin CATCH
if(@@trancount>0)
ROLLBACK
end CATCH
于 2017-12-28T08:14:48.437 回答
0

事实证明,在我的一个大型存储过程中隐藏了一个删除语句,该语句写入不正确导致了问题。

在寻找这个问题的原因时,我还有一个 DBA 和我坐在一起,他确定了我的 SSIS 流程中正在重组索引的一部分;但它正在这样做,因为包继续运行并填充所有必要的基础表(包括带有孤立记录的表)。据他说,重组或重建表上的索引,同时尝试向这些表中添加或删除记录也可能导致此问题。尽管在我的具体情况下,它是错误编写的单个删除语句。

于 2018-03-20T16:11:00.363 回答