【问题标题】:How to find all tables where trigger does not exist如何查找不存在触发器的所有表
【发布时间】:2017-07-01 22:04:24
【问题描述】:

前几天我们发现一个表有一个ModifiedDate 列,但发现没有触发器来实际更新该列。现在我正在尝试编写一个脚本来查找所有具有ModifiedDate 列但没有更新它的触发器的表。

这是我目前所拥有的:

SELECT so.name AS 'TableName', sc.name AS 'ColumnName', tr.name AS 'Trigger'
FROM sys.objects so
INNER JOIN sys.columns sc ON sc.object_id = so.object_id
LEFT JOIN sys.triggers tr ON so.object_id=tr.object_id
WHERE so.type = 'U' AND sc.name LIKE '%ModifiedDate%' 
AND tr.type = 'TR'

首先,我想查找同时具有列和触发器的所有表。我能够找到所有带有ModifiedDate 列的表,但是当我添加最后一个过滤器AND tr.type = 'TR' 时,它什么也不返回。我检查了那里的表格,其中包含我正在寻找的列和触发器,所以我希望在列表中看到这些。

【问题讨论】:

  • 您对WHERE 的使用会将LEFT OUTER JOIN 转换为INNER JOIN。您必须允许 NULL 值或将适当的条件移至 ON 子句。
  • @HABO 而事实上他加入了错误的专栏......?他的查询,具有正确的列名 (parent_id) 执行他所需要的。 “首先,我想查找所有同时具有列和触发器的表。”

标签: tsql ssms sql-server-2016


【解决方案1】:
SELECT so.name AS 'TableName', sc.name AS 'ColumnName', tr.name AS 'Trigger'
FROM sys.objects so
INNER JOIN sys.columns sc ON sc.object_id = so.object_id
LEFT JOIN sys.triggers tr ON so.object_id=tr.parent_id
WHERE so.type = 'U' AND sc.name LIKE '%ModifiedDate%' 
AND tr.type = 'TR'

您在触发器上的加入错误

清理您的查询,找到所有可能没有触发器的表:

Select  t.name As 'TableName'
       ,c.name As 'ColumnName'
       ,tr.name As 'Trigger'
From    sys.tables t
Join    sys.columns c On c.object_id = t.object_id
Left Join sys.triggers tr On t.object_id = tr.parent_id
Where   c.name Like '%ModifiedDate%'
        And tr.name Is Null

我取出了一些多余的东西。对表进行选择消除了查找 Type = 'U' 的需要,并且 parent_id\object_id 关系使得您不需要使用 Type = 'TR' 子句来强制执行它。

【讨论】:

  • sys.triggers 上的 object_id 是触发器的对象。要查找附加了触发器的表,您需要 parent_id
  • 我试过这个查询,但只得到一张表的结果。似乎左连接不起作用?
  • 查询完全符合您的要求。在表具有名为 ModifiedDate 的列的情况下,使用触发器拉回所有表的值。我刚刚对其进行了测试,第一次得到了一行,在我添加了第二个具有相应列名和触发器的表之后,又得到了一行。你加入的逻辑很时髦,它不适用于下一步,但我的回答完全符合要求。
  • 我运行的每个测试都返回了预期的结果。您是否已验证您的列名等是否正确?
  • 感谢您的帮助!您列出的第二个查询对我有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-22
  • 2014-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多