多维模型程序集管理

Microsoft SQL Server Analysis Services 提供了许多用于多维表达式(MDX)和数据挖掘扩展插件(DMX)语言的内部函数,旨在完成从标准统计计算到遍历层次结构中的成员的所有内容。 但是,与任何其他复杂且可靠的产品一样,始终需要进一步扩展此类产品的功能。

因此,Analysis Services 允许将程序集添加到 Analysis Services 实例或数据库。 程序集允许你使用任何公共语言运行时 (CLR) 语言(如 Microsoft Visual Basic .NET 或 Microsoft Visual C#)创建外部用户定义函数。 还可以使用组件对象模型(COM)自动化语言,例如 Microsoft Visual Basic 或 Microsoft Visual C++。

重要

COM 程序集可能会带来安全风险。 由于此风险和其他注意事项,COM 程序集在 SQL Server 2008 Analysis Services(SSAS)中已弃用。 未来版本可能不支持 COM 程序集。

程序集允许扩展 MDX 和 DMX 的业务功能。 将所需的功能构建到库中,例如动态链接库(DLL),并将库作为程序集添加到 Analysis Services 实例或 Analysis Services 数据库。 然后,库中的公共方法将作为用户定义的函数公开给 MDX 和 DMX 表达式、过程、计算、操作和客户端应用程序。

可以将具有新过程和函数的程序集添加到服务器。 可以使用程序集来增强或添加服务器未提供的自定义功能。 通过使用程序集,可以将新函数添加到多维表达式(MDX)、数据挖掘扩展插件(DMX)或存储过程。 程序集从运行自定义应用程序的位置加载,并且程序集二进制文件的副本与服务器中的数据库数据一起保存。 删除程序集时,也会从服务器中删除复制的程序集。

程序集可以是两种不同的类型:COM 和 CLR。 CLR 程序集是在 .NET Framework 编程语言(如 C#、Visual Basic .NET)中开发的程序集,托管C++。 COM 程序集是必须在服务器上进行注册的 COM 组件库。

可以向 ServerDatabase 对象添加程序集。 服务器程序集可由连接到服务器的任何用户或服务器中的任何对象调用。 只能由 Database 连接到数据库的对象或用户调用数据库程序集。

简单 Assembly 对象由基本信息(名称和 ID)、文件集合和安全规范组成。

如果调试文件随程序集文件一起加载,则文件集合引用加载的程序集文件及其相应的调试 (.pdb) 文件。 程序集文件从应用程序定义文件的位置加载,并将副本连同数据一起保存在服务器中。 每次启动服务时,程序集文件的副本都用于加载程序集。

安全规范包括权限集和用于运行程序集的模拟。

调用 User-Defined 函数

在程序集中调用用户定义的函数就像调用内部函数一样执行,只不过必须使用完全限定的名称。 例如,返回 MDX 预期类型的用户定义的函数包含在 MDX 查询中,如以下示例所示:

Select MyAssembly.MyClass.MyStoredProcedure(a, b, c) on 0 from Sales  

还可以使用 CALL 关键字调用用户定义的函数。 必须为返回记录集或 void 值的用户定义的函数使用 CALL 关键字,并且如果用户定义函数依赖于 MDX 或 DMX 语句或脚本上下文中的对象(如当前多维数据集或数据挖掘模型),则不能使用 CALL 关键字。 在 MDX 或 DMX 查询外部调用的函数的常见用途是使用 AMO 对象模型来执行管理功能。 例如,如果要在 MDX 语句中使用函数 MyVoidProcedure(a, b, c) ,将采用以下语法:

Call MyAssembly.MyClass.MyVoidProcedure(a, b, c)  

程序集通过开发一次通用代码并将其存储在单个位置来简化数据库开发。 客户端软件开发人员可以创建用于 Analysis Services 的函数库,并将其与其应用程序一起分发。

程序集和用户定义的函数可以复制 Analysis Services 函数库或其他程序集的函数名称。 只要你使用用户定义函数的完全限定名称来调用,Analysis Services 就会使用正确的方法。 出于安全考虑,并且为了消除在不同类库中调用重复名称的可能性,Analysis Services 要求仅对存储过程使用完全限定的名称。

若要从特定 CLR 程序集调用用户定义的函数,用户定义的函数前面有程序集名称、完整类名和过程名称,如下所示:

AssemblyNameFullClassNameProcedureNameArgument1Argument2、...)

为了向后兼容早期版本的 Analysis Services,还可以接受以下语法:

AssemblyNameFullClassNameProcedureNameArgument1Argument2、...)

如果 COM 库支持多个接口,接口 ID 也可用于解析过程名称,如下所示:

AssemblyNameInterfaceIDProcedureNameArgument1Argument2、...)

安全

程序集的安全性基于 .NET Framework 安全模型,这是代码访问安全模型。 .NET Framework 支持代码访问安全机制,该机制假定运行时可以托管完全信任和部分信任的代码。 受 .NET Framework 代码访问安全性保护的资源通常由托管代码包装,该代码在启用对资源的访问权限之前需要相应的权限。 仅当调用堆栈中的所有调用方(在程序集层)均具有相应资源权限时,此权限要求才得到满足。

对于程序集,使用对象上的Assembly属性传递PermissionSet执行权限。 托管代码接收的权限由安全策略确定。 非由 Analysis Services 托管的环境中已经有三个级别的策略在实施:企业、计算机和用户。 代码接收的权限的有效列表由这三个级别获取的权限的交集决定。

Analysis Services 在托管 CLR 时向 CLR 提供主机级安全策略级别;此策略是低于始终生效的三个策略级别的附加策略级别。 此策略是为 Analysis Services 创建的每个应用程序域设置的。

Analysis Services 主机级策略是由系统程序集的 Analysis Services 固定策略以及用户程序集的用户指定策略组成的组合。 分析服务主机策略中由用户指定的部分是基于程序集所有者为每个程序集指定三个权限类别之一:

权限设置 DESCRIPTION
Safe 提供内部计算权限。 此权限存储桶不分配访问 .NET Framework 中任何受保护资源的权限。 如果未使用 PermissionSet 属性指定权限,则这是程序集的默认权限策略。
ExternalAccess 提供与 Safe 设置相同的访问权限,并具有访问外部系统资源的额外功能。 此权限存储桶不提供安全保证(尽管可以保护此方案),但它确实提供可靠性保证。
Unsafe 不提供任何限制。 对于在此权限集下运行的托管代码,无法保证安全性和可靠性。 在此信任级别运行的代码被授予任何权限,包括管理员添加的自定义权限。

当 Analysis Services 托管 CLR 时,基于堆栈的权限检查会在与原生 Analysis Services 代码的边界处停止。 Analysis Services 程序集中的任何托管代码始终属于前面列出的三个权限类别之一。

COM(或非托管)程序集例程不支持 CLR 安全模型。

模仿

每当托管代码访问 Analysis Services 外部的任何资源时,Analysis Services 都遵循与 ImpersonationMode 程序集的属性设置关联的规则,以确保访问发生在适当的 Windows 安全上下文中。 由于使用 Safe 权限设置的程序集无法访问 Analysis Services 外部的资源,因此这些规则仅适用于使用 ExternalAccessUnsafe 权限设置的程序集。

  • 如果当前执行上下文对应于 Windows 身份验证登录名,并且与原始调用方(即中间没有 EXECUTE AS)的上下文相同,Analysis Services 将在访问资源之前模拟 Windows 身份验证登录名。

  • 如果中间的 EXECUTE AS 更改了原始调用方的上下文,则对外部资源的访问尝试将会失败。

ImpersonationMode 属性可以设置为 ImpersonateCurrentUserImpersonateAnonymous。 默认设置在 ImpersonateCurrentUser 当前用户的网络登录帐户下运行程序集。 ImpersonateAnonymous如果使用此设置,则执行上下文对应于服务器上的 Windows 登录用户帐户IUSER_servername。 这是 Internet 来宾帐户,该帐户在服务器上具有有限的权限。 在此上下文中运行的程序集只能访问本地服务器上的有限资源。

应用程序域

Analysis Services 不会直接公开应用程序域。 由于一组程序集在同一应用程序域中运行,应用程序域在执行时可以通过使用 .NET Framework 中的 System.Reflection 命名空间或其他方式相互发现,并且能够以晚期绑定的方式调用它们。 此类调用将受 Analysis Services 基于授权的安全性使用的权限检查的约束。

不应依赖于在同一应用程序域中查找程序集,因为应用程序域边界和进入每个域的程序集由实现定义。

另请参阅

设置存储过程的安全性
定义存储过程