我在SQL Server 2008中工作。我的任务是编写存储过程,以便在我们将其移动到星型模式数据仓库环境之前对外部数据进行一些数据验证。请求的一种测试是从外部事实数据表到维度表的域完整性/参考查找。为此,我使用以下技术:
SELECT
some_column
FROM some_fact_table
LEFT JOIN some_dimension_table
ON
some_fact_table.some_column = some_dimension_table.lookup_column
WHERE
some_fact_table.some_column IS NOT NULL
AND
some_dimension_table.lookup_column IS NULL
SELECT子句将匹配错误表的列定义,我将最终通过SSIS将输出移动到该表中。因此,SELECT子句实际上看起来像:
SELECT
primary_key,
'some_column' AS Offending_Column,
'not found in lookup' AS Error_Message,
some_column AS Offending_Value
但是,因为事实表非常大,我们希望最小化我们必须从中选择的次数。因此,我只对每个事实表进行一次查询,以检查相关的每个列,如下所示:
SELECT
primary_key,
'col1|col2|col3' AS Potentially_Offending_Columns,
'not found in lookup|not found in lookup|not found in lookup' AS Error_Messages,
col1 + '|' + col2 + '|' + col3 AS Potentially_Offending_Values
FROM fact_table
LEFT JOIN dim_table1
ON
fact_table.col1 = dim_table1.lookup_column
LEFT JOIN dim_table2
ON
fact_table.col2 = dim_table2.lookup_column
LEFT JOIN dim_table3
ON
fact_table.col2 = dim_table3.lookup_column
WHERE
dim_table1.lookup_column IS NULL
OR
dim_table2.lookup_column IS NULL
OR
dim_table3.lookup_column IS NULL
这有一些问题。 (1)如果任何源列行为空,则Offending_Values中的字符串连接将导致NULL。如果我用ISNULL包装每一列(并将空值换成类似空字符串的东西),那么我将无法判断测试是否因为源中的真空字符串或者交换为空而导致失败串。 (2)如果只有一个列在查找中失败,那么错误消息仍然会读取'not found in lookup|not found in lookup|not found in lookup'
,即我无法分辨哪些列实际失败。 (3)输出中的Potentially_offending_Columns列将始终为静态,这意味着我无法通过查看它来判断是否有任何列失败。
所以,实际上,我的错误表存在一些设计问题。在这种情况下,是否有标准的输出错误表的方法?或者,如果没有,我需要修复什么才能使输出可读且有用?
答案 0 :(得分:0)
我不知道您的数据是什么样的,但是不能使用带有ISNULL的空字符串,您不能返回单词FAIL或对您有意义的内容。您可以为“未在查找中找到”列中的情况进行操作。
CASE WHEN Col1 IS NULL THEN 'not found in lookup' ELSE '' END + '|' +
CASE WHEN Col2 IS NULL THEN 'not found in lookup' ELSE '' END + '|' +
CASE WHEN Col3 IS NULL THEN 'not found in lookup' ELSE '' END AS Error_Messages,
ISNULL(col1,'FAIL') + '|' + ISNULL(col2,'FAIL') + '|' + ISNULL(col3,'FAIL') AS Potentially_Offending_Values