How to encrypt all existing stored procedures of a database

前端 未结 8 1975
后悔当初
后悔当初 2021-02-10 10:13

Is there any possibility to encrypt all existing stored procedures of a SQL Server 2008 database AFTER they have been created via an SQLCMD script?

The reason I want to

8条回答
  •  面向向阳花
    2021-02-10 10:43

    I have made an update to one of the above answers by removing the dependency on the initial Begin Tag. I had a situation where not all my stored procedures had BEGIN and END.

    I used the AS clause instead and also used a case sensitive version of the charindex (by adding a collation)

    Its not a perfect solution but helped in getting more of my stored procedures encrypted.

    Here is my updated code:

                IF OBJECT_ID('tempdb..#backup', 'U') IS NOT NULL 
    
                 BEGIN
    
                 DROP TABLE #backup
    
                 END
    
                CREATE TABLE #backup
    
                 (
    
                 id BIGINT IDENTITY(1, 1),
    
                 sptext NVARCHAR(MAX) NOT NULL,
    
                 spname NVARCHAR(100) NOT NULL,
    
                 encrypttext NVARCHAR(MAX) NULL,
    
                 encryptstatus BIT NOT NULL
    
                 DEFAULT ( 0 )
    
                 )
    
                DECLARE @sptexttable TABLE
    
                 (
    
                 id BIGINT IDENTITY(1, 1),
    
                 sptext NVARCHAR(MAX),
    
                 spname NVARCHAR(100)
    
                 )
    
                INSERT INTO @sptexttable ( sptext, spname )
    
                 SELECT [text],
    
                 [name]
    
                 FROM syscomments
    
                 JOIN sysobjects ON syscomments.id = sysobjects.id
    
                 AND sysobjects.xtype = 'p'
    
                DECLARE @sptext NVARCHAR(MAX)
    
                DECLARE @spname NVARCHAR(100)
    
                DECLARE @counter INT
    
                SET @counter = 1
    
                WHILE @counter <= ( SELECT MAX(id)
    
                 FROM @sptexttable
    
                 )
    
                 BEGIN
    
    
    
    
    
                 BEGIN TRY
    
    
    
    
    
                 INSERT INTO #backup ( sptext, spname )
    
                 SELECT sptext,
    
                 spname
    
                 FROM @sptexttable
    
                 WHERE id = @counter
    
                 END TRY
    
                 BEGIN CATCH
    
                 END CATCH
    
                  IF NOT EXISTS ( SELECT [name]
    
                 FROM sysobjects
    
                 WHERE [name] = 'CaseSensitiveIndex'
    
                 AND xtype = 'FN' ) 
    
                 BEGIN
                    
    
                 EXEC (
                 'CREATE FUNCTION dbo.CaseSensitiveIndex(@source nvarchar(max), @pattern VARCHAR(50))
                RETURNS int
                BEGIN  
                    return   CHARINDEX(@pattern COLLATE Latin1_General_CS_AS, @source COLLATE Latin1_General_CS_AS) 
                END; '
                )
                end
    
    
                 IF NOT EXISTS ( SELECT [name]
    
                 FROM sysobjects
    
                 WHERE [name] = 'ce_LastIndexOf'
    
                 AND xtype = 'FN' ) 
    
                 BEGIN
    
                    
    
                 EXEC
    
                 ( 'CREATE FUNCTION ce_LastIndexOf 
    
                    (@strValue VARCHAR(max),
    
                    @strChar VARCHAR(50)) 
    
                RETURNS INT
    
                AS
    
                BEGIN
    
                DECLARE @index INT
    
                    
    
                SET @index = 0
    
    
    
                WHILE CHARINDEX(@strChar, @strValue) > 0
    
                    BEGIN
    
                        SET @index = @index + CASE WHEN CHARINDEX(@strChar, @strValue) > 1 
    
                                     THEN 
    
                                        (LEN(@strValue) - LEN(SUBSTRING(@strValue,CHARINDEX(@strChar, @strValue) + LEN(@strChar),LEN(@strValue)))) 
    
                                     ELSE 
    
                                        1 
    
                                     END
    
                        SET @strValue = SUBSTRING(@strValue,CHARINDEX(@strChar, @strValue) + len(@strChar),LEN(@strValue))    
    
                    END
    
    
    
                    RETURN @index 
    
                END'
    
                 )
    
    
    
                 END 
    
                 DECLARE @tempproc NVARCHAR(MAX) 
    
                 DECLARE @procindex INT
    
                 DECLARE @beginindex INT
    
                 DECLARE @header NVARCHAR(MAX)
    
                 DECLARE @asindex INT
    
                 DECLARE @replacetext NVARCHAR(MAX)
    
    
    
                 SET @tempproc = ( SELECT sptext
    
                 FROM @sptexttable
    
                 WHERE id = @counter
    
                 )
    
    
    
                 IF ( SELECT CHARINDEX('CREATE PROC', UPPER(@tempproc))
    
                 ) > 0 
    
                 BEGIN
    
                 BEGIN TRY
    
                 SELECT @procindex = CHARINDEX('PROC', UPPER(@tempproc))
    
                 PRINT @procindex
    
                 SELECT @beginindex=(select dbo.CaseSensitiveIndex(@tempproc, 'AS'))
    
    
                 if(@beginindex=0) begin set @beginindex=( SELECT dbo.ce_lastindexof(@tempproc, 'AS'))end
                 SELECT @header = SUBSTRING(@tempproc, @procindex,
    
                 @beginindex )
    
                 SELECT @asindex = ( SELECT dbo.ce_lastindexof(@header, 'AS')
    
                 - 2
    
                 )
    
                 SELECT @replacetext = STUFF(@header, @asindex, 3,
    
                 CHAR(13) + 'WITH ENCRYPTION'
    
                 + CHAR(13) + 'AS' + CHAR(13))
    
                 SET @tempproc = REPLACE(@tempproc, @header, @replacetext)
    
    
    
                                    
    
    
    
                 END TRY
    
                 BEGIN CATCH
    
                 END CATCH
    
    
    
                    
    
                 END
    
    
    
                 UPDATE @sptexttable
    
                 SET sptext = @tempproc
    
                 WHERE id = @counter 
    
    
    
                --PLAY HERE TO MAKE SURE ALL PROCS ARE ALTERED
    
                 UPDATE @sptexttable
    
                 SET sptext = ( SELECT REPLACE(sptext, 'CREATE PROC',
    
                 'ALTER PROC')
    
                 FROM @sptexttable
    
                 WHERE id = @counter
    
                 )
    
                 WHERE id = @counter 
    
    
    
                 SELECT @sptext = sptext,
    
                 @spname = spname
    
                 FROM @sptexttable
    
                 WHERE id = @counter
    
    
                 BEGIN TRY
    
    
                 EXEC ( @sptext)
    
                 UPDATE #backup
    
                 SET encrypttext = @sptext,
    
                 encryptstatus = 1
    
                 WHERE id = @counter
    
                 END TRY
    
                 BEGIN CATCH
    
                 PRINT 'the stored procedure ' + @spname
    
                 + ' cannot be encrypted automatically'
    
                 END CATCH
    
    
    
    
    
                 SET @counter = @counter + 1
    
                 END
    
                SELECT *
    
                FROM #backup where encryptstatus =0
    

提交回复
热议问题