如何从过程代码中删除 WITH ENCRYPTION - 通过 T-SQL

Mar*_*lli 2 sql-server stored-procedures t-sql sql-server-2014

我有很多过程在创建它们时使用了WITH ENCRYPTION选项。

您可以在下面的图片中看到这一点,例如:

在此处输入图片说明

问题是当我想保存我以前版本的存储过程时,我无法得到预期的结果,如下图所示。

在此处输入图片说明

我备份存储过程代码的方式在下面的链接上: 如何备份存储过程的当前代码及其权限?

select 'Proc' = SCHEMA_NAME(p.schema_id)+'.'+p.name
    , 'Type' = per.state_desc, 'Permission' = per.permission_name
    , 'Login' = pri.name, 'Type' = pri.type_desc 
    , *
From sys.procedures as p
left join sys.database_permissions as per on p.object_id = per.major_id
left join sys.database_principals as pri on per.grantee_principal_id = pri.principal_id
where ...
Run Code Online (Sandbox Code Playgroud)

有没有办法在保存之前从存储过程的代码中删除 WITH ENCRYPTION?

前提是我拥有​​该程序的所有权。

下面的链接上有一个几乎重复的问题 How to view an encrypted view or stored procedure

但是,在这个问题上,我拥有数据库。我是系统管理员。我可以使用任何资源,但我想要通过 T-SQL 的解决方案。

spa*_*dba 5

正如 Sebastian Meine 对问题How to view an encrypted view or stored procedure的回答中所述,有一个 T-SQL 解决方案来执行解密。可以在Sebastian 的博客上找到这样做的代码。

该解决方案需要与 DAC 连接,因此您可以通过 T-SQL 存储过程进行连接的选项很少。一种可能的方法是使用链接服务器:

DECLARE @srv nvarchar(4000);
SET @srv = 'ADMIN:' + @@SERVERNAME; -- gather this server name

-- Create the linked server
EXEC master.dbo.sp_addlinkedserver
    @server     = N'DAC_LOOPBACK',
    @srvproduct = N'SQLServ', -- it’s not a typo: it can’t be “SQLServer”
    @provider   = N'SQLNCLI', -- change to SQLOLEDB for SQLServer 2000
    @datasrc    = @srv;

-- Set the authentication to "current security context"
EXEC master.dbo.sp_addlinkedsrvlogin
    @rmtsrvname  = N'DAC_LOOPBACK',
    @useself     = N'True',
    @locallogin  = NULL,
    @rmtuser     = NULL,
    @rmtpassword = NULL;


EXEC master.dbo.sp_serveroption 
    @server=N'DAC_LOOPBACK', 
    @optname=N'rpc', 
    @optvalue=N'true'
EXEC master.dbo.sp_serveroption 
    @server=N'DAC_LOOPBACK', 
    @optname=N'rpc out', 
    @optvalue=N'true'
GO
Run Code Online (Sandbox Code Playgroud)

一旦您拥有使用 DAC 的环回链接服务器,您就可以执行 Sebastian 的存储过程来收集加密文本。不幸的是,该过程返回一个 XML 列(不能通过链接服务器返回),因此您必须更改最后一个SELECT以返回 nvarchar(max):

SET @cmd = N'SELECT CAST(@plain AS NVARCHAR(MAX)) AS [object_definition for ' + 
    REPLACE(@object_name, ']', ']]') + ']';
Run Code Online (Sandbox Code Playgroud)

现在您可以使用链接服务器调用该过程:

EXEC DAC_LOOPBACK.SomeDatabase.dbo.ObjectEncryptionCracker
   'SomeEncryptedProcedure'
Run Code Online (Sandbox Code Playgroud)

我推荐这种方法吗?一定不行!
跟踪存储过程中的更改的正确方法是源代码控制,正如您在原始问题中已经被告知的那样。不要依赖此代码来备份您的代码(它不受支持并使用了多种技巧)。帮自己一个忙,将您的数据库对象置于源代码控制之下。