You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何查找SQL Server 2008 R2中聚合两表数据的SQL作业

嘿,刚好我对SQL Server 2008 R2的作业查询熟得很,给你几个实用的方法来找用到表A或表B的SQL作业:

方法1:直接扫描作业步骤的命令文本

这个方法最直接,适合作业步骤里直接写TSQL语句的场景,直接在作业步骤的命令里搜索表名:

SELECT 
    j.name AS 作业名称,
    js.step_id AS 步骤ID,
    js.step_name AS 步骤名称,
    js.command AS 执行命令
FROM 
    msdb.dbo.sysjobs j
JOIN 
    msdb.dbo.sysjobsteps js ON j.job_id = js.job_id
WHERE 
    -- 替换成你的实际表名,比如表A是PurchaseReceipts,表B是PurchasePriceInfo
    (js.command LIKE '%表A%' OR js.command LIKE '%表B%')
    -- 加上架构匹配,避免误判(比如表名是dbo.TableA)
    OR (js.command LIKE '%[.]表A%' OR js.command LIKE '%[.]表B%')
ORDER BY 
    j.name, js.step_id;

注意:如果表名在SQL里用了别名(比如SELECT * FROM 表A a),或者被放在变量里,这个方法可能漏查,所以需要结合其他方法验证。

方法2:检查作业调用的存储过程

很多作业会调用存储过程来执行逻辑,这时候得去查存储过程的定义里有没有用到目标表:

-- 先提取作业里调用的所有存储过程
WITH 作业调用的存储过程 AS (
    SELECT 
        j.name AS 作业名称,
        js.step_id AS 步骤ID,
        js.step_name AS 步骤名称,
        -- 简单提取存储过程名,复杂场景可能需要调整正则逻辑
        SUBSTRING(js.command, CHARINDEX('EXEC ', js.command) + 5, 
                  CHARINDEX(' ', js.command, CHARINDEX('EXEC ', js.command) + 5) - (CHARINDEX('EXEC ', js.command) + 5)) AS 存储过程名
    FROM 
        msdb.dbo.sysjobs j
    JOIN 
        msdb.dbo.sysjobsteps js ON j.job_id = js.job_id
    WHERE 
        js.command LIKE '%EXEC %' OR js.command LIKE '%EXECUTE %'
)
-- 检查这些存储过程的定义是否包含目标表
SELECT 
    作业名称,
    步骤ID,
    步骤名称,
    存储过程名,
    sm.definition AS 存储过程定义
FROM 
    作业调用的存储过程 jp
JOIN 
    sys.procedures p ON p.name = jp.存储过程名
JOIN 
    sys.sql_modules sm ON p.object_id = sm.object_id
WHERE 
    sm.definition LIKE '%表A%' OR sm.definition LIKE '%表B%'
    OR sm.definition LIKE '%[.]表A%' OR sm.definition LIKE '%[.]表B%';

方法3:通过对象依赖关系全面查找

这个方法更准确,能找出所有间接依赖表A或表B的作业(比如作业调用视图,视图依赖表;或者调用函数,函数依赖表):

-- 先找出所有引用表A或表B的数据库对象(存储过程、视图、函数等)
WITH 依赖对象 AS (
    SELECT 
        referencing_id,
        referencing_schema_name,
        referencing_entity_name,
        referencing_class_desc
    FROM 
        sys.dm_sql_referencing_entities('dbo.表A', 'OBJECT')
    UNION ALL
    SELECT 
        referencing_id,
        referencing_schema_name,
        referencing_entity_name,
        referencing_class_desc
    FROM 
        sys.dm_sql_referencing_entities('dbo.表B', 'OBJECT')
)
-- 再找出调用这些依赖对象的作业
SELECT 
    j.name AS 作业名称,
    js.step_id AS 步骤ID,
    js.step_name AS 步骤名称,
    js.command AS 执行命令,
    do.referencing_entity_name AS 依赖对象名称
FROM 
    依赖对象 do
JOIN 
    sys.procedures p ON p.object_id = do.referencing_id
JOIN 
    msdb.dbo.sysjobsteps js ON js.command LIKE '%' + p.name + '%'
JOIN 
    msdb.dbo.sysjobs j ON j.job_id = js.job_id
ORDER BY 
    j.name, js.step_id;

额外提醒

  • 记得把代码里的表A表B替换成你的实际表名,最好加上架构(比如dbo.PurchaseReceipts),避免混淆。
  • LIKE查询可能会有假阳性结果(比如命令里刚好有和表名一样的字符串),所以查到结果后最好手动点开作业步骤验证一下。
  • 如果你的作业是SSIS包类型,2008 R2里需要从msdb.dbo.sysssispackages提取包的XML内容来搜索表名,这个操作相对复杂,要是需要的话可以再细化。

内容的提问来源于stack exchange,提问作者Petras Paludnevičius

火山引擎 最新活动