SQL Server CLR集成是否支持配置文件?

zhe*_*ang 7 c# sql-server configurationmanager sqlclr configuration-files

我使用SQL Server CLR集成来创建一个ASSEMBLY.

加载命令: CREATE ASSEMBLY TcpClr FROM 'G:\TcpClrTest.dll' WITH PERMISSION_SET = UNSAFE

没有App.Config

DLL代码包含: string ip=ConfigurationManager.AppSettings["connection"].ToString();

App.config还包含:

<appSettings> <add key="connection" value="127.0.0.1"/> </appSettings>

但是当我执行PROCEDURE时,SQL Server显示错误 System.NullReferenceException

SQL Server CLR集成是否支持App.config文件?

Sol*_*zky 13

您需要将sqlservr.exe.config文件放在该实例的根文件夹的\ Binn文件夹中.例如:

C:\ Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn

如果您使用的是SQL Server 2008 R2(SP1)或更高版本,则应该能够通过以下查询找到确切的位置,该查询显示了sqlservr.exe的完整路径:

SELECT [filename] FROM sys.dm_server_services WHERE servicename LIKE N'SQL Server (%';
Run Code Online (Sandbox Code Playgroud)

在您的代码中,您需要在顶部显示以下行:

using System.Configuration;
Run Code Online (Sandbox Code Playgroud)

然后这将工作:

[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
public static SqlString GetConfig(SqlString WhichOne)
{
    ConfigurationManager.RefreshSection("connectionStrings");
    return ConfigurationManager.ConnectionStrings[WhichOne.Value].ToString();
}
Run Code Online (Sandbox Code Playgroud)

在内容sqlservr.exe.config文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
   <connectionStrings>
      <add name="Stuff" connectionString="Trusted_Connection=true; Enlist=false;" />
      <add name="ClrTest" connectionString="boo hoo" />
   </connectionStrings>
</configuration>
Run Code Online (Sandbox Code Playgroud)

请务必注意,如"使用应用程序配置..."链接中所述,对配置文件所做的更改不会立即可用.无论其,你就不会需要做的是文章中提到的方法之一(即强制重新加载DBCC FREESYSTEMCACHE,并重新启动SQL服务器).获取当前信息所需的只是通过ConfigurationManager.RefreshSection(string sectionName)重新加载您正在使用的特定部分,如上例所示.请参阅下面有关使用和性能的说明.

资源:


此外,除非您绝对需要,否则不应将程序集创建为UNSAFE.如果您只是尝试与其他计算机建立TCP连接,那应该只需要EXTERNAL_ACCESS.


用途和表现

正如Joe B在下面评论中所建议的那样,该RefreshSection操作的性能略有下降.如果包含刷新的代码每隔几分钟被调用一次以上,那么它就会产生明显的影响(由于配置文件的频率变化不足,这种影响是不必要的).在这种情况下,您需要RefreshSection从经常调用的代码中删除调用,并单独处理刷新.

一种方法是使用SQLCLR存储过程或标量函数来执行刷新而不执行任何其他操作.只要对配置文件进行了更改,就可以执行此操作.

另一种方法是卸载App Domain,该域将在下次引用该数据库中的任何SQLCLR对象时重新加载配置文件.在特定数据库中重新加载所有应用程序域的一种相当简单的方法(但不是在整个实例中)是将TRUSTWORTHY设置再次打开然后再关闭,或者再次关闭然后再打开,具体取决于该设置的当前状态.下面的代码将检查该设置的当前状态并相应地翻转它:

IF (EXISTS(
    SELECT  sd.*
    FROM    sys.databases sd
    WHERE   sd.[name] = DB_NAME() -- or N'name'
    AND     sd.[is_trustworthy_on] = 0
   ))
BEGIN
    PRINT 'Enabling then disabling TRUSTWORTHY...';
    ALTER DATABASE CURRENT SET TRUSTWORTHY ON;
    ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;
END;
ELSE
BEGIN
    PRINT 'Disabling then enabling TRUSTWORTHY...';
    ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;
    ALTER DATABASE CURRENT SET TRUSTWORTHY ON;
END;
Run Code Online (Sandbox Code Playgroud)

不要使用任何更激烈的方法 - DBCC FREESYSTEMCACHE禁用然后启用clr enabled系统设置,重新启动实例等 - 因为几乎没有必要这样做.特别是重新启动实例,或者DBCC FREESYSTEMCACHE删除整个实例的所有缓存数据,这不仅仅影响SQLCLR.

关于LINUX上的SQL SERVER的更新

从2017版本开始,SQL Server现在可以在Linux上使用(woo hoo!).但是,它似乎从应用程序配置文件中读取并不能在Linux上运行.我尝试过很多sqlservr.exe.[Cc]onfigsqlservr.[Cc]onfig等等的组合,并 没有任何工作.指定配置文件不能正常工作,因为需要EXTERNAL_ACCESS权限,SAFELinux上只允许使用程序集(至少目前为止).如果我找到一种方法让它工作,我会在这里发布详细信息.