0

我在两个不同的数据库(在同一台服务器上)中有两个表,可能具有不同的模式。Table 1master table,所有的更新都会直接去那里。Table 2将是mirrored:我需要以某种方式实时保持表 2 与表 1 相同。

问题是表 2 可能有额外的列、不同的列数据类型、添加的主键、添加的外键等。尽管如此,表 2 需要支持某些遗留前端正在生成的所有查询。

我今天计划通过尝试在触发器内针对第二个数据库中的表 2 重新执行更新、插入和删除语句来反映这些可能“不同”的情况。如果触发器失败,整个操作就会失败,所以理论上这应该保持表相同。

不过,我一直坚持获取触发触发器的实际 sql 语句。

fn_get_sql


DECLARE @Handle varbinary(64)
select @Handle = sql_handle FROM master..sysprocesses WHERE spid = @@SPID
select text FROM ::fn_get_sql(@Handle)

这将返回触发器的 sql,而不是语句。

DBCC INPUTBUFFER(@@SPID)

这将返回 sql 语句的前 256 个字符.. 不够好。

我的第一个问题是:如何获取触发 sql 2000 中触发器的 sql 语句?

我的第二个问题是:有没有更好的方法来做到这一点?我可以使用复制来复制一个表与另一个表具有不同架构的表(额外的列,列的不同数据类型等)

4

3 回答 3

1

我认为您可能误解了触发器的工作原理;无需查找导致触发器触发的查询文本。

SQL Server 触发器对名为insertedand的临时表进行操作,其中包含受语句deleted影响的行的新旧版本。UPDATE对于INSERTandDELETE操作,仅分别填充insertedor表。deleted有关更多详细信息,请参阅SQL 2000 触发器文档

应该可以使用触发器来维护table 2,假设其中的行与 之间存在一对一的关系table 1

您可能考虑的另一种选择是替换table 2为基于 的视图table 1,只要转换很简单。只要视图与原始对象相同并且授予了必要的权限,更改对客户端应用程序应该是透明的。
这需要进行测试,因为如果您需要将其他表连接到table 2数据类型已更改的列上,它可能会对性能产生负面影响。

table 1复制并不真正适合此任务,如果并且table 2在同一个数据库中,则根本无法工作;复制发布者和订阅者必须位于不同的数据库中。

于 2012-08-04T06:41:29.613 回答
1

我建议使用从主表返回数据的视图,该数据格式化为旧应用程序期望的结构。没有延迟问题,没有重复数据存储。

于 2012-08-04T06:58:41.447 回答
1

我有不同的方法来回答这两个问题。我通常避免使用触发器,直到它是最后的选择,因为它会在数据库上增加不必要的开销。

触发器和存储过程的比较

  • 在数据库中查看表关系、约束、索引、存储过程很容易,但很难查看触发器。
  • 触发器执行对客户端应用程序不可见。它们不可见或可以在调试代码中跟踪。
  • 很容易忘记触发器,如果​​没有文档,新开发人员将很难弄清楚它们的存在。
  • 每次更新数据库字段时都会运行触发器,这会增加系统开销。它使系统运行更慢。

说得够多了,这就是为什么我更喜欢存储过程。您可以通过代理创建一个作业文件(例如 ex :它每 30 分钟或任何其他时间执行一次)。您可以使用该逻辑插入该作业文件。通过这种方式,您的数据table2将接近实时。

现在参考创建代理: http:
//msdn.microsoft.com/en-us/library/ms191128 (v=sql.90).aspx
http://msdn.microsoft.com/en-us/library/ms181153 (v=sql.105).aspx

于 2012-08-04T02:43:23.907 回答