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

标签 c# sql-server configuration-files sqlclr configurationmanager

我使用 SQL Server CLR Integration 创建一个 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>

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

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

最佳答案

您需要将 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 (%';

在您的代码中,您需要在顶部添加这一行:

using System.Configuration;

然后这将起作用:

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

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>

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

资源:


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


使用和性能

正如 Joe B 在 comment below 中所建议的那样,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;

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

有关 Linux 上 SQL Server 的更新

从 2017 版开始,SQL Server 现在可在 Linux 上使用(太棒了!)。但是,从应用程序配置文件中读取似乎在 Linux 上有效。我已经尝试了 sqlservr.exe.[Cc]onfigsqlservr.[Cc]onfig 等的许多组合,但没有任何效果。无法指定配置文件,因为这需要 EXTERNAL_ACCESS 权限,并且在 Linux 上只允许使用 SAFE 程序集(至少目前是这样)。如果我找到让它工作的方法,我会在此处发布详细信息。

关于c# - SQL Server CLR 集成是否支持配置文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28183917/

相关文章:

c# - TableLayoutPanel 大小调整

c# - 如何设置 submit sm 让客户端使用它在 jamaa smpp 中的属性来发送消息?

c# - 将文件保存在 SQL Server 数据库中

SQL:替换字符串中的特定字符

java - log4j.properties 到 log4j2 log2.xml

ios - 在运行时切换Firebase配置文件

c# - 如何在 TextBox 中自动显示文本开头

sql - 动态将supervisor节点更改为null

php - 如果我使用CodeIgniter中的函数或类来生成表来存储我的用户信息,它是否安全或可能?

webpack - 如何防止 secret 数据包含在 WebPack bundle 中