Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# CLR触发状态 我考虑使用CLR触发器代替传统的T-SQL,因为我需要使用一些已经在C语言中实现的逻辑。我知道SQL server支持CLR集成,在我看来,这似乎是一个值得尝试的解决方案_C#_Sql Server_Triggers_Sqlclr - Fatal编程技术网

C# CLR触发状态 我考虑使用CLR触发器代替传统的T-SQL,因为我需要使用一些已经在C语言中实现的逻辑。我知道SQL server支持CLR集成,在我看来,这似乎是一个值得尝试的解决方案

C# CLR触发状态 我考虑使用CLR触发器代替传统的T-SQL,因为我需要使用一些已经在C语言中实现的逻辑。我知道SQL server支持CLR集成,在我看来,这似乎是一个值得尝试的解决方案,c#,sql-server,triggers,sqlclr,C#,Sql Server,Triggers,Sqlclr,但是,我想要执行的操作可能会有点慢。速度不够慢,不足以完全排除在触发动作中使用它们,但在插入数十万条记录时,速度可能明显较慢。最慢的部分可以从缓存中获益匪浅,我认为这将是很少的缓存未命中和数千次缓存命中。在这一点上,所有这些都引出了一个问题:CLR触发器可以有任何状态吗?更重要的是,这种状态的生命周期是什么 我想我可以使用trigger类的静态字段来保存一些状态,但我不知道它何时被初始化(服务器何时启动?在事务启动时?未指定?)。我不确定这是否是安全的途径,因此询问在CLR触发器中使用某些状态的

但是,我想要执行的操作可能会有点慢。速度不够慢,不足以完全排除在触发动作中使用它们,但在插入数十万条记录时,速度可能明显较慢。最慢的部分可以从缓存中获益匪浅,我认为这将是很少的缓存未命中和数千次缓存命中。在这一点上,所有这些都引出了一个问题:CLR触发器可以有任何状态吗?更重要的是,这种状态的生命周期是什么

我想我可以使用trigger类的静态字段来保存一些状态,但我不知道它何时被初始化(服务器何时启动?在事务启动时?未指定?)。我不确定这是否是安全的途径,因此询问在CLR触发器中使用某些状态的常见做法是什么(如果有的话)

为了避免混淆:我需要缓存CLR对象,而不是一些SQL查询的结果,所以这不是关于SQL Server本身在缓存方面有多好,我想缓存一些不属于数据库的数据。此外,我认为CLR不是因为我不能在T-SQL中进行字符串操作和绑定检查。我需要执行一些在CLR类库中实现的逻辑,这些逻辑有很多依赖项。在这种情况下,我是否应该使用触发器是另一个几乎与此无关的问题

非常感谢

PS:我将非常感谢您对本主题的任何评论和见解,即使是那些没有直接回答我问题的评论和见解,但请不要说“触发器是邪恶的,永远不应该使用”和“CLR集成很慢,是一个主要的兼容性问题”。此外,我知道它可能会对某些人大喊“过早优化”,但目前我只想知道我的优化选项是什么,因为我对SQL server中的CLR集成还不熟悉。我不会优化它,除非分析结果表明是这样,但我不想实现整个过程来意识到它太慢,我对此无能为力


我使用SQL Server 2008和.NET 3.5。

虽然可以在SQLCLR触发器类中使用
静态
类字段来缓存值,但有几件事需要非常小心:

  • 您计划缓存多少数据?您不希望占用太多的内存,而SQL Server应该将其用于查询

  • 每个程序集所有者的每个数据库都有一个AppDomain(即程序集上的
    授权
    )。这意味着任何特定程序集中的代码在所有SQL Server会话(即SPID)中共享。如果数据只是查找数据,并且不会根据哪个进程与静态字段交互而改变,那么这就可以了。但是,如果每个进程的数据不同,那么这将产生“奇数”行为,除非您将当前TransactionID之类的值与该进程关联

  • 如果数据是每个进程的,假设您找到了区分每个特定SPID/会话的方法,那么您将如何清理旧数据?它将存在于内存中,直到显式删除或卸载AppDomain。对于要与所有人共享的公共查找数据来说,这不是一个问题,因为这种类型的数据不会随着每个新流程的增加而增加。但除非清除,否则每个过程的数据将持续增加

  • AppDomains可以在任何时候出于各种原因卸载(内存压力、程序集的删除/重新创建、与程序集相关的安全更改、与数据库相关的安全更改、运行DBCC FREESYSTEMCACHE('ALL'))等)。如果一个进程依赖于前一个进程缓存的数据,那么正在缓存的数据可能会导致顺序进程之间产生不同的结果,那么这就不能保证正常工作。如果在进程之间丢弃缓存只会导致需要重新加载缓存,那么应该没有问题

  • 其他注意事项(但无需谨慎):

  • 当在程序集中调用第一个方法时,将加载AppDomain,其中程序集中存在的数据库以及作为该程序集授权人的用户当前没有运行AppDomain

  • 由于上述原因之一,AppDomains将一直保持加载状态,直到SQL Server卸载它们,但这些情况都不一定会发生。这意味着,AppDomain可以在很长时间内保持加载状态(即,直到服务器/服务重新启动)

  • 第一次引用每个程序集内部的方法时,将加载该程序集

  • 为了利用加载事件,可以将代码放置在静态类构造中。请注意,没有可用的
    SqlContext
    ,因此不能在使用进程内上下文连接的静态类构造函数中创建任何
    SqlConnection
    (即
    Context Connection=true


  • 在内存中缓存?这是SQL Server已经擅长的事情之一。@Mitch Wheat:您能详细说明一下吗?对于规格和配置正确的SQL Server上的大多数数据库,80%的“热”页将由RAM提供,而不是由文件系统提供(大型数据库除外)。如果不是这样的话,你还有其他问题…(不是我的反对票)你的触发器有表访问权限吗?如果是(这当然是一个触发器),那么CLR不是最好的选择。它很慢:您选择了错误的解决方案。没有任何调整可以优化它:这就是我们使用纯SQL的原因。你的P.S.令人恼火:接受你选择的产品的局限性solution@Mitch小麦:我需要缓存POCO,而不是关系数据