我在两个不同的数据库(在同一台服务器上)有两个表,可能有不同的模式。 Table 1
是master table
,所有更新都将直接发送到那里。 Table 2
将成为mirrored
:我需要保持表2与表1的实时相同。
问题是表2可能有额外的列,不同的列数据类型,添加的主键,添加的外键等。尽管如此,表2需要支持某些传统前端正在生成的所有查询。 / p>
我今天计划通过尝试在触发器内的第二个数据库中对表二重新执行更新,插入和删除语句来镜像这些可能“不同”。如果触发器失败,则整个操作失败,因此理论上这应该使表保持相同。
但我仍然坚持获取触发触发器的实际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语句?
我的第二个问题是:有更好的方法吗?我可以使用复制来复制表,其中一个表具有与另一个表不同的模式(额外的列,列的不同数据类型等)。
答案 0 :(得分:1)
我有不同的方法来回答这两个问题。我通常会避免使用触发器,直到它成为最后一个选择,因为它会在数据库上添加不必要的开销。
触发器和存储过程之间的比较
够了,这就是为什么我更喜欢存储过程。您可以通过代理创建一个作业文件(比方说:它每隔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
答案 1 :(得分:1)
我认为你可能误解了触发器是如何工作的;没有必要找到导致触发器触发的查询文本。
SQL Server触发器对名为inserted
和deleted
的临时表进行操作,这些表包含受UPDATE
语句影响的行的新旧版本。对于INSERT
和DELETE
操作,仅分别填充inserted
或deleted
表。
有关详细信息,请参阅SQL 2000 trigger documentation。
应该可以使用触发器来维护table 2
,假设其中的行与table 1
之间存在一对一的关系。
您可以考虑的另一个替代方案是使用基于table 2
构建的视图替换table 1
,只要转换很简单即可。只要视图与原始对象具有相同的权限并且授予了必要的权限,则更改应对客户端应用程序透明
这需要进行测试,因为如果您需要在数据类型已更改的列上将其他表连接到table 2
,则可能会产生负面的性能影响。
复制不适用于此任务,如果table 1
和table 2
位于同一数据库中,则根本不起作用;复制发布者和订阅者必须位于不同的数据库中。
答案 2 :(得分:1)
我建议使用一个视图,将主表格中的数据格式化为您的遗留应用程序所期望的结构。没有延迟问题,没有重复的数据存储。