How do I find all stored procedures that insert, update, or delete records?

后端 未结 3 2113
名媛妹妹
名媛妹妹 2020-12-03 19:14

Is it possible, without parsing source, to select a list of all sproc names that insert, update, or delete records? I need to create a TSQL utility script that will do this.

3条回答
  •  时光说笑
    2020-12-03 19:49

    Thanks to Cade Roux's answer i was able to get very close with this:

    DECLARE @RoleName nvarchar(255)
    SET @RoleName = 'READONLYUSER'
    
    DECLARE @ROUTINE_NAME nvarchar(255)
    DECLARE RoutineList Cursor FOR
    SELECT ROUTINE_NAME
    FROM    INFORMATION_SCHEMA.ROUTINES
    WHERE   (OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)), N'IsSchemaBound') IS NULL OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)), N'IsSchemaBound') = 0)
        AND NOT ROUTINE_NAME like 'sel%'
        AND NOT ROUTINE_NAME like 'sp_upd%'
        AND NOT ROUTINE_NAME like 'sp_sel%'
        AND NOT ROUTINE_NAME like 'sp_ins%' 
    OPEN RoutineList
    FETCH NEXT FROM RoutineList 
    INTO @ROUTINE_NAME
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
        EXEC ('EXEC sp_refreshsqlmodule ''' + @ROUTINE_NAME + '''')
    
        FETCH NEXT FROM RoutineList INTO @ROUTINE_NAME
    END
    CLOSE RoutineList
    DEALLOCATE RoutineList
    
    
    DECLARE GrantList Cursor FOR
    SELECT DISTINCT
        so.name AS ROUTINE_NAME
    FROM sysobjects so
    LEFT JOIN (
        SELECT 
            so.name,
            so2.name AS [table],
            sd.is_updated
            FROM sysobjects so
            INNER JOIN sys.sql_dependencies sd ON so.id = sd.object_id
            INNER JOIN sysobjects so2 ON sd.referenced_major_id = so2.id
            WHERE so.xtype = 'p'
            and is_updated = 1
    ) Updates ON so.name = Updates.name
    WHERE 
        so.xtype = 'p' -- procedure
        AND Updates.name is null
        AND so.name NOT LIKE '%[_]%'
    ORDER BY so.name
    
    OPEN GrantList
    FETCH NEXT FROM GrantList 
    INTO @ROUTINE_NAME
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
        print 'GRANT EXECUTE ON [dbo].['+@ROUTINE_NAME+'] TO ['+@RoleName +']   '  
    
    
        FETCH NEXT FROM GrantList INTO @ROUTINE_NAME
    END
    CLOSE GrantList
    DEALLOCATE GrantList
    

提交回复
热议问题