我正在寻找一种非破坏性地改变数据的方法。我有一个表有不应编辑的数据 - 它是主数据。我想对这些数据进行用户编辑,但为了保持主数据的完整性,我创建了第二个表,它是主表结构的镜像。
我的想法是,我基本上会创建一个视图(vAdjustedData),使得这些数据一起UNIONed,为我提供了一个最新版本的数据源。 (这样做的目的是允许用户在调整后的表中撤消其数据,并将主表数据恢复为当前数据。)
表中的列可以为空。这个想法是,当用户希望进行编辑时,将复制主记录,应用更改,然后保存到调整表中。我对UNION的想法会用调整后的记录掩盖原始主记录,这样当放在视图中时,我将获得“当前”数据。删除此调整后,视图将“自动”回滚。
所以我有Table_Master和Table_Adjusted。 Table_Master有一个主键。 Table_Adjusted也有一个主键,但它是Table_Master主键的外键。如果两个表都有一个varchar列,我希望写一个与此类似的视图:
(SELECT ID, Value
FROM Table_Adjusted)
UNION
(SELECT ID, Value
FROM Table_Master
WHERE ID NOT IN (SELECT ID FROM Table_Adjusted))
上面的UNION应该带来所有调整后的值,然后是主控中没有调整记录的所有值。
这是正确的方法吗?对我而言似乎效率低下。我认为EXCEPT会起作用(使用SQL2K8),但这似乎不合适。
答案 0 :(得分:2)
我假设您希望调整后的表格仅调整值,而不是添加或删除值。您的查询的缺点是理论上可以添加原始表中甚至不存在的新值。此版本可以防止这种可能的风险:
SELECT Table_Master.ID,
CASE WHEN Table_Adjusted.ID IS NULL THEN Table_Master.Value
ELSE Table_Adjusted.Value
END AS Value
FROM Table_Master
LEFT JOIN Table_Adjusted
ON Table_Master.ID = Table_Adjusted.ID
此外,您的查询使用UNION DISTINCT,但实际上您只需要一个UNION ALL。这个略微修改的查询版本应该运行得稍快一些:
SELECT ID, Value
FROM Table_Adjusted
UNION ALL
SELECT ID, Value
FROM Table_Master
WHERE ID NOT IN (SELECT ID FROM Table_Adjusted)