我正在 Visual Studio 2012 中创建一个 SQLCLR 存储过程。我有这些目标平台的选项:

没有 SQL Server 2008 R2 特定选项吗?这是因为 SQL 2008 R2与 SQL Server 2008共享相同的兼容性级别100?
从最近两天开始,我可以在 SQL Server 错误日志中看到以下内容。
AppDomain 2 (mssqlsystemresource.dbo[runtime].1) unloaded.
&
AppDomain 2 (mssqlsystemresource.dbo[runtime].1) is marked for unload due to memory pressure.
Run Code Online (Sandbox Code Playgroud)
我有这样的系统环境:
OS- microosft windows server 2012 R2 Standard
processors - Intel(R) Xeon(R) CPU E5-2670 0 @2.60 GHz
Installed Memory (RAM) - 8GB
Hardware Information - VMWare, Inc. VMware Virtual Platform
SQL Server - Microsoft SQL Server Enterprise (64-bit)
Run Code Online (Sandbox Code Playgroud)
我已经在本地服务器中查看了昨天的事件日志。我找到了这些事件
Server Name ID Severity Source Log Date and Time
ABC 1008 Error Microsoft-Windows-Perflib Application 10/01/2015 2:21
ABC 2 Error TeamCentral Application …Run Code Online (Sandbox Code Playgroud) 每当将行插入某个表时,我都想添加一个触发器。触发器将触发 CLR 存储过程,该过程将执行数据库工作以外的其他操作,例如将 JSON 字符串写入 txt 文件并更新不同类型数据库的系统日志。
我的双手被束缚在使用这项技术上。最初我们打算编写一个 Windows 服务,它会定期扫描表,然后在插入新记录时运行该程序。
我的问题是:
我可以将 DLL 托管在不同的服务器上,以便在那里运行,或者当我部署 CLR 存储过程 dll 时,它是否总是在 SQL Server 数据库实例中运行?
我问的原因是我们不希望此代码减慢数据库服务器的速度,这可能会通过在代码中执行这些其他任务来实现。
运行所有这些命令的登录名是sysadminSQL 2012 Developer 实例上服务器角色的成员。它是部署到的数据库的所有者。EXTERNAL ACCESS ASSEMBLY已授予此 DB 中的登录权限。还尝试了以下所有内容作为sa登录无济于事。
alter database test set trustworthy on
go
create assembly [icsharpcode.sharpziplib]
from 'C:\Workspace\111\icsharpcode-SharpZipLib-4f2d664\bin\Release\ICSharpCode.SharpZipLib.dll'
with permission_set = UNSAFE --< This works!
go
create assembly OutOfRowCompression
from 'C:\Workspace\Sandbox\OutOfRowCompression\OutOfRowCompression\bin\Debug\OutOfRowCompression.dll'
with permission_set = UNSAFE --< This fails!
go
Run Code Online (Sandbox Code Playgroud)
最后一个命令失败:
消息 10327,级别 14,状态 1,第 1 行 CREATE ASSEMBLY 为程序集“OutOfRowCompression”失败,因为程序集“OutOfRowCompression”未被授权用于 PERMISSION_SET = UNSAFE。当以下任一情况为真时,程序集被授权:数据库所有者 (DBO) 具有 UNSAFE ASSEMBLY 权限并且数据库具有 TRUSTWORTHY 数据库属性;或者程序集使用证书或非对称密钥签名,该密钥具有具有不安全程序集权限的相应登录名。
收到错误后,我使用新的非对称密钥对程序集进行了签名key1.pfx,并将其添加到主数据库中:
CREATE ASYMMETRIC KEY key1
FROM executable
FILE = 'C:\Workspace\Sandbox\OutOfRowCompression\OutOfRowCompression\bin\Debug\OutOfRowCompression.dll'
Run Code Online (Sandbox Code Playgroud)
验证密钥是否存在: …
我有一个 CLR 存储过程(除其他外)调用 TSQL 存储过程。TSQL 存储过程运行一些动态 SQL,并在运行前打印 SQL 以进行调试。PRINT语句中没有任何内容显示在客户端中。当我们需要排除故障时,有什么好方法可以让我们看到这些命令?
示例代码:
dll中的C#代码
public static void Print_CLR()
{
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
conn.Open();
using (SqlCommand c = new SqlCommand("exec dbo.Print_TSQL", conn))
{
c.ExecuteNonQuery();
}
}
}
Run Code Online (Sandbox Code Playgroud)
CLR 调用的 Proc
public static void Print_CLR()
{
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
conn.Open();
using (SqlCommand c = new SqlCommand("exec dbo.Print_TSQL", conn))
{
c.ExecuteNonQuery();
}
}
}
Run Code Online (Sandbox Code Playgroud) 我有以下 CLR 存储过程,该过程在此命令上引发错误
xmlDoc.LoadXml(inputXml);
Run Code Online (Sandbox Code Playgroud)
代码
public static int spGetTaxOfficeXML(SqlXml _inputXml)
{
// this procedure rename Row elements name with NodeName attribute value
string inputXml = _inputXml.ToString();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(inputXml);
// procedure Logic
SqlContext.Pipe.Send(inputXml);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当 XML 文本作为文本位于 Visual Studio 内的变量内部时,效果很好。但是当我将代码作为 CLR 上传到 SQL Server 并尝试从 SQL Management Studio 执行它时:
DECLARE @XML XML
SET @XML = '<NodeA><NodeB></NodeB><NodeC AttributeX=""><Row NodeName="RowA" AttributeA="" AttributeB="abcd" AttributeC="efgh" /><Row NodeName="RowB" AttributeA="wxyz" /><Row NodeName="RowC" AttributeB="qwer" AttributeC="tyui" /><Row NodeName="RowD" AttributeA="stuv" AttributeB="erty" AttributeC="fghj" /></NodeC></NodeA>'
EXEC …Run Code Online (Sandbox Code Playgroud) 我知道 CLR 存储过程在过程代码中更有效,而 T-SQL 更适合查询 - 但是我很难决定使用什么来满足我的特定需求,我想知道是否还有其他事情我在做决定时应该考虑一下。
我计划创建的代码涉及查询一组数据、实现一些算法(随着时间的推移会变得更加复杂)以及将数据插入到数据库中。此存储过程将由调度程序部署 - 最有可能是 azure webJobs,因为据我所知 Azure SQL 不支持 db 作业。
为什么我想到使用 C#
假设我可以从我的服务器加载 DAL 库,并利用 OOP - 我想我可以为这个问题实现一个对编码器更友好的解决方案 - 至于性能,我认为它会更好或至少在比较中不明显。
为什么我想到使用 T-SQL
我实际上并不认为这是一个更好的解决方案,但可能有一些我忽略的东西可能是 T-SQL 的一个很好的例子,因为对我来说它没有任何意义。
最重要的是
有没有办法可以创建一个 T-SQL 存储过程,调用一个带有复杂对象作为参数的 C# 存储过程 - 执行我的算法并返回要插入的数据,然后从 T-SQL 插入它?似乎是最优雅、性能最好的 (?) 解决方案(假设它是可能的,并且从 T-SQL 调用 CLR 没有任何缺点)。
使用以下代码,我使用 csc 来编译 dll。然后我将程序集添加到 sql server 2014 使用
CREATE ASSEMBLY ReplaceMultiWord from 'd:\bcp\ReplaceMultiWord.dll' WITH PERMISSION_SET = SAFE;
Run Code Online (Sandbox Code Playgroud)
然后成功添加了第一个功能
CREATE FUNCTION dbo.ReplaceMultiWord
(@inputString AS NVARCHAR(MAX), @replacementSpec AS XML) RETURNS NVARCHAR(MAX)
AS
EXTERNAL NAME ReplaceMultiWord.UserDefinedFunctions.ReplaceMultiWord;
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试添加第二个功能时
CREATE FUNCTION dbo.CanReplaceMultiWord
(@inputString AS NVARCHAR(MAX), @replacementSpec AS XML) RETURNS BIT
AS
EXTERNAL NAME ReplaceMultiWord.UserDefinedFunctions.CanReplaceMultiWord;
Run Code Online (Sandbox Code Playgroud)
我收到错误
Could not find method 'CanReplaceMultiWord' for type 'UserDefinedFunctions' in assembly 'ReplaceMultiWord'
Run Code Online (Sandbox Code Playgroud)
下面是我的代码。为什么 sql server 看不到第二个函数?
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Xml;
public partial class …Run Code Online (Sandbox Code Playgroud) 我们有一个主分析 SP,它调用 100 个其他子 SP,所有这些都对同一组数据(声明)进行操作,检查其是否存在某些业务规则和输出差异。
SP 不需要全部按顺序运行,它们可以分成多个部分,这些部分依赖于前面的部分(顺序),但在该部分内独立(并行)。
在查看了许多选项(例如 Service Broker、Agent Jobs、Batch Files、SSIS 等)后,我使用此CLR 代码来并行化各个部分,并极大地提高了性能。
但是,当我同时运行多个 (5, 10, 15) 个主 SP(每个 SP 分析不同的声明)时,性能会随着并发性的增加而逐渐下降。我猜这是因为通过 CLR 创建多个并行线程的开销。我还看到 sp_who2 中有很多 XTP_THREAD_POOL 会话空闲。
有没有人使用 CLR 在关键 OLTP 生产工作负载中并行化存储过程?
是否有任何性能优化 SQL CLR 的最佳实践?
在开销使事情变得更糟之前,是否有可以打开的并行线程数量的阈值?
如果我的系统有 20 个内核,是否意味着创建 > 20 个并行线程没有帮助?
主要问题我们需要在MS SQL Server 2019上使用正则表达式,能力至少达到POSIX正则表达式的水平。
这个来自 stackoverflow 的问答正确地得出结论,如果您的查询必须依赖正则表达式,您应该使用 CLR。这篇 Readgate文章详细阐述了这种方法。所以我和我的一位同事提出了这个解决方案,但我的另一位同事断然表示,在这里使用 CLR 会给安全性和稳定性带来巨大风险,而使用外部脚本(Python 或 R)更安全。
这似乎是一个可疑的说法,因为CLR 中的用户代码是可以管理的,所以也许正好相反,但我没能说服我的同事。
在我绝望中写的另一个问题中,因为我被迫使用外部脚本并且仍然产生一个极快的查询。SQLpro 用户在他的评论中指出:
就安全性而言,使用 Python 或 R 可能比使用 CLR 更糟糕!
我倾向于相信。
所以我有两个问题:
sql-server regular-expression sql-clr python external-scripts
sql-clr ×10
sql-server ×9
c# ×2
compression ×1
memory ×1
parallelism ×1
python ×1
t-sql ×1
xml ×1