我们继承了一个遗留的 SQL 2005 数据库。设置了两个程序集供其中一个数据库中的触发器使用(哎哟)。文件夹/文件被错误删除了。它们是由前一位员工从他的桌面文件夹安装的,并且没有签入源代码管理(哎哟)。现在 dll 已经消失,我们担心重新启动。SQL 2005 是否以某种方式复制/重命名/存储这些 dll,从而意味着重新启动服务器不会产生问题?
答案1
你很幸运,如果原始部署的程序集只是丢失了,你仍然可以将程序集二进制文件导出为十六进制字符串。
1.打开 SSMS 并导航到可编程性 -> 程序集。您应该会看到已注册的程序集,我用红色突出显示了我的程序集。
2.右键单击程序集并将其脚本化到新的查询窗口:
3.完成后,你会看到类似这样的内容:
CREATE ASSEMBLY [Microsoft.SqlServer.Types]
AUTHORIZATION [sys]
FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000...[snipped]
WITH PERMISSION_SET = UNSAFE
行FROM 0x4D5A90000...
是实际的汇编代码,编码为一个大的十六进制字符串。请参阅下文了解如何导出回文件格式。
确保您还编写了依赖于此程序集的所有函数、触发器等的脚本。您可以通过在 SSMS 中对程序集执行“查看依赖关系”来找到它们。
您应该能够毫无顾忌地重新启动服务器,因为程序集是从系统数据库表之一存储和加载的(我记不起它的名字了,但可以通过sys.assembly_files
在系统视图中,用户只能在文件系统上操作。
但是,如果您不想重新启动,请按照上述说明进行导出,然后在另一个 SQL 2005 实例上重新创建,以确保一切完好无损。
如何将已注册的程序集导出到文件
根据我在此主题您可以将已注册的程序集导出回常规文件。如果使用 Visual Studio 部署程序集,则可能还会有一些源代码对象存储在 SQL Server 中,这当然是一个好处。例如,当我从 VS2010 部署后查询我的开发服务器时,我发现了以下内容:
SELECT * FROM sys.assembly_files
如您所见,有几个文件与SqlServerProject2
(程序集 ID = 65540)。我们可以通过运行这个脚本来导出所有这些文件:
DECLARE @assembly_id int, @name nvarchar(260), @content varbinary(MAX)
DECLARE @ObjectToken INT, @outputdir nvarchar(20)
-- Get assembly id from querying sys.assembly_files
SET @assembly_id = 65540 -- IMPORTANT: SET THIS VALUE
SET @outputdir = 'D:\Data\Assemblies\' -- AND THIS PATH
DECLARE assy_cursor CURSOR FOR
SELECT name, content
FROM sys.assembly_files
WHERE assembly_id = @assembly_id
OPEN assy_cursor
FETCH NEXT FROM assy_cursor INTO @name, @content
WHILE @@FETCH_STATUS = 0
BEGIN
SET @name = @outputdir + REPLACE(@name, '\', '-')
print 'Saving: ' + @name
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @content
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @name, 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken
FETCH NEXT FROM assy_cursor INTO @name, @content
END
CLOSE assy_cursor
DEALLOCATE assy_cursor
您需要设置这两个变量:
SET @assembly_id = 65540
SET @outputdir = 'D:\Data\Assemblies\'
该@outputdir
路径需要位于 SQL Server 有权限写入的地方。
执行脚本后,您将得到一个或多个文件。如果您没有全部源代码,则始终可以使用 .NET Reflector 反编译输出的程序集。
笔记:OLE 自动化(sp_OAxxxxx
存储过程)在 SQL Server 中默认是禁用的,但你可以通过执行以下操作来启用它:
use master
go
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO