Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SSIS-如果源数据集中的任何行缺少值,则失败?_Sql Server_Ssis - Fatal编程技术网

Sql server SSIS-如果源数据集中的任何行缺少值,则失败?

Sql server SSIS-如果源数据集中的任何行缺少值,则失败?,sql-server,ssis,Sql Server,Ssis,假设我有以下数据: FirstName | LastName | Age | Date Added to Database (derived column) John | Doe | 23 | dd/mm/yyyy Jane | Doe | 31 | dd/mm/yyyy Bob | | 40 | dd/mm/yyyy Janet | Smith | | dd/mm/yyyy 我想将它从Exce

假设我有以下数据:

FirstName | LastName | Age | Date Added to Database (derived column) 
John      | Doe      | 23  | dd/mm/yyyy
Jane      | Doe      | 31  | dd/mm/yyyy
Bob       |          | 40  | dd/mm/yyyy
Janet     | Smith    |     | dd/mm/yyyy
我想将它从Excel/平面文件源引入Sql Server。但是,如果源数据集中的任何一行缺少值,我希望任务完全失败。到目前为止,我已经看过一些教程,我们可以在其中执行以下操作:

其中,如果具有空值的记录包含空值,则将对其进行拆分。但是,如果任何值为null,我根本不想插入任何值,而是希望执行类似于在出现故障时发送电子邮件通知缺少值之类的操作


这在SSIS中可能吗?可以用临时台等来完成吗

这可以通过暂存表来完成。对于示例数据,您将使用下面的DDL

诀窍是在每一列上都有一个NOTNULL约束。有关该约束的更多信息,请参阅上的这篇博客文章

SSIS尝试插入空值时将失败。这不是最优雅的解决方案,但它能满足您的要求,而且不会产生太多开销

CREATE TABLE Staging
(
    FirstName VARCHAR(50) NOT NULL
    , LastName VARCHAR(50) NOT NULL
    , Age INT NOT NULL
    , DateAdded DATETIME NOT NULL
)

没有什么现成的方法可以直接支持这个场景,但我可以想出一些方法,您可以拼凑起来实现您的请求

最干净/最容易实现的方法就是将所有数据填充到一个临时表中,因为我很懒,所以我会在表定义中添加一个计算列,将行标记为某个地方有null

ALTER TABLE dbo.stageData 
ADD HasNull AS (CASE WHEN Col1 IS NULL OR Col2 IS NULL THEN 'Y' ELSE 'N');
然后在数据流之后添加两个执行SQL任务。第一个发送电子邮件(假设你已经设置了msdb.dbo.sp_send_dbmail),我会做些什么

IF EXISTS (SELECT * FROM dbo.StageData AS SD WHERE SD.HasNull = 'Y')
BEGIN
    EXECUTE msdb.dbo.sp_send_db_mail @recipient = 'ocean800', @subject = 'Null detected';
END 
然后我将有一个执行SQL任务,该任务将数据从stage捕捉到最终的表中。在这里仔细检查我的逻辑,因为我还没有编码。它可能需要是任意的,或者只是重复sendmail逻辑,并将insert作为ELSE子句。见鬼,那可能更简单

INSERT INTO dbo.Final SELECT * FROM dbo.StageData AS SD WHERE NOT EXISTS (SELECT * FROM dbo.StageData AS SDI SDI.HasNull ='Y');
没有stage表的方法是双重处理文件。第一个数据流将是平面文件源到条件拆分,然后。。。不管怎样。我将简单地使用行计数转换,它将填充您创建的名为rowsnll的SSIS变量。数据流运行后,您的值将为零(适于加载)或大于零-发送电子邮件

将数据流任务分为数据流任务,数据流任务实际存储到我们的表和通知中(发送电子邮件任务、执行SQL任务发送电子邮件等等)。 这里的技巧是修改父任务(数据流)和子路径之间的前置约束。将其设置为表达式和约束。约束保持成功,约束为@[User::rowsnll]==0和@[User::rowsnll]>0


其他不太好的方法可能是指定OLE DB目标保留默认设置(每批的行数为空,最大插入提交大小为max int),该设置为“全部”或“无”提交-您只需要一些东西来破坏隐式事务,因此在对HasNull路径进行条件拆分时,将行路由到引发错误事件的脚本任务。那会把货物压死的。或者在这些列上使用NOT NULL说明符定义目标表,然后数据将加载或不加载,您只需将您喜欢的电子邮件任务添加到数据流的失败先例约束中,以便在加载失败时通知。

您完全可以使用暂存表作为数据流的中间点,然后在进一步移动SQL之前验证SQL中所需的任何逻辑。这种方法非常简单,并且还有一个额外的好处,即每当进程失败时,您的暂存表将包含来自最新文件的所有数据,因此调查它更容易

我能想到的所有备选方案在性能和/或所需资源方面都要差得多,而且通常不会使用。例如,从理论上讲,可以通过将文件数据加载到,在将脚本中的值发送到输出缓冲区时检查这些值,并在数据出现任何错误时引发异常。如果此数据流没有失败,那么下一步可能会将该记录集中的数据加载到实际表中


免责声明:上述的选择是如此的笨拙和低效,不应该被认为是可行的方法。我不知道该在哪里开始描述它的缺点。个人来说,只有当我的实际目标是“尽我所能而不给我的雇主一个正式的案例”时,我可能会考虑一些类似的事情。

+1关于给自己留一条面包屑痕迹,我说的还不够好。
每当进程失败时,您的暂存表将包含最新文件中的所有数据,因此调查起来更容易,因为您知道会发生不好的事情