Sql server 在SQL Server中,截取并更改列设置为的值

Sql server 在SQL Server中,截取并更改列设置为的值,sql-server,tsql,foreign-keys,Sql Server,Tsql,Foreign Keys,我正在努力改进一个遗留数据库。一个问题是它缺少很多外键关系。在涉及的某些列中,关联的应用程序将字段设置为空字符串,而本应将字段设置为null。我想做的是拦截任何设置该列的尝试,并在将空字符串应用于表之前将其替换为NULL。我能想到的唯一解决方案是使用INSTEAD of触发器,但涉及到一些大型(列数)表,我不喜欢这会导致维护问题(如果有人添加了列,他们也必须更新触发器)。我还担心这种方法对性能的影响 我是否遗漏了一些可能有用的技巧?理想的解决方案是修复遗留应用程序,但在begin移植到C#的(漫

我正在努力改进一个遗留数据库。一个问题是它缺少很多外键关系。在涉及的某些列中,关联的应用程序将字段设置为空字符串,而本应将字段设置为null。我想做的是拦截任何设置该列的尝试,并在将空字符串应用于表之前将其替换为NULL。我能想到的唯一解决方案是使用INSTEAD of触发器,但涉及到一些大型(列数)表,我不喜欢这会导致维护问题(如果有人添加了列,他们也必须更新触发器)。我还担心这种方法对性能的影响

我是否遗漏了一些可能有用的技巧?理想的解决方案是修复遗留应用程序,但在begin移植到C#的(漫长的)过程中,它是一个巨大的VB6应用程序,没有人愿意投入资源来修复生命周期结束代码中的问题

谢谢, 凯文

很清楚,我关心的不是列中是否存在空字符串,而是该字符串阻止我创建外键关系。一般来说,我不允许在主键表中创建虚拟行来涵盖这一点。尽管重命名主键表和使用旧名称创建一个视图以过滤掉这些伪行可能需要一些时间。虽然很乱,但这是最后的选择。

困难的选择


如果担心性能,那么可能在晚上运行mysql事件,将空字符串更改为null?如果可以等到那时。然而,这仍然意味着您必须维护代码。我想,如果您可以通过约定指出哪些字段需要更新,那么从存储的进程反映模式并非不可能?

如果您想要做的是在值不是空字符串的情况下强制执行外键约束(这里尝试横向思考),然后,可以将计算列添加到表中:

ALTER TABLE Tab1 ADD Col1Fixed as CASE WHEN Col1 <> '' THEN Col1 END persisted
ALTER Tab1 ADD Col1Fixed as CASE当Col1“”时,则Col1 END保持不变
然后使用该列作为外键约束的基础,而不是Col1。然后,至少在应用程序编写应该存在的值时,您可以获得完整性


很抱歉,这不是您问题的直接答案,但正如我在评论中所说的,据我所知,唯一直接的方法(动态重新写入列值)是触发器。

这仍然会破坏引用完整性-主键表在外键列中不包含空字符串的对应项。好的,这很有意义,尤其是在编辑之后。我能想到的唯一其他方法是拦截对DB的调用,并在调用DB之前修复它,在Java中使用类似AOP的东西。我不确定VB是否有AOP实现?我甚至不确定AOP是否有帮助。快速浏览一下遗留应用程序,我可以看到它使用ADODB记录集的直接更新访问数据,调用存储过程,动态生成SQL并执行它。显然,我可以修改存储的进程,尽管它们通常会生成干净的数据,但拦截动态SQL需要我在拦截时解析SQL——这不是小事。如果您无法(正如您所指出的那样),INSTEAD of触发器是唯一适合这里的东西要更改应用程序,应用程序将直接插入到表中。是的,应用程序将直接插入到表中,很可能位于多个位置。非常混乱:-(我认为你是对的,但只是偶然的……这是一个有趣的想法。我需要考虑一下它的含义,但它确实有潜力。此外,我可以建立一个命名约定,这样我们就可以抓住所有这些,并删除它们一旦应用程序终于移植。