标签: sql-clr

SQL Server:如何在不阻塞触发触发器的事务的情况下获得触发器的响应能力?

今天的一个线程中,我希望在插入记录时立即执行代码,而不是求助于轮询。

触发器是强大的工具,但也是放置真实代码的危险场所,因为如果代码缓慢或阻塞,事务就会阻塞,这可能会成为一个真正的问题。

就我而言,轮询是不可行的。我真的需要我的代码在记录出现时立即执行。Windows 应用程序正在向表中插入数据。我没有应用程序的来源,无法更改它。我可以完全访问 SQL Server。

但是将严肃的代码放入触发器中确实是一种不好的做法。

所以问题就变成了:与触发器一样响应的触发器的替代方案是什么?(或者几乎和响应一样......延迟 1-5 秒就可以了,但是 30 秒的轮询周期确实令人不快。要运行的代码需要 0-3 秒才能完成。)

约束:

  • 我只能访问数据库,不能访问应用程序
  • SQL Server 2005 和 2008
  • 可行的。我们不希望发明一些疯狂的东西,添加大量基础设施或大型新系统。我们有一个应用程序。它与 SQL Server 对话。添加更多层概率是不可能的。
  • 实现另一个服务器应用程序(如 msg 队列服务器等)对于这个项目是不可行的。这东西一天只会开一到十五次。

手头的工具(不全面): - .NET - Python - C#

如果可能的话,希望避免使用 xp_cmdshell。

sql-server sql-clr python

6
推荐指数
1
解决办法
737
查看次数

GZipStream/DeflateStream 压缩替代方案

我创建了一个简单的 CLR 函数来压缩/解压缩NVARCHAR列:

[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
public static SqlBinary Compress( string str ){
    if( str == null ){return new SqlBinary();}

    if( String.IsNullOrEmpty( str ) ){str = " ";}

    byte[] bytes = Encoding.Unicode.GetBytes( str );
    using( MemoryStream msi = new MemoryStream( bytes ) ){
        using( MemoryStream mso = new MemoryStream() ){
            using( GZipStream gs = new GZipStream( mso, CompressionMode.Compress ) ){
                msi.CopyTo( gs );
            }
            return new SqlBinary( mso.ToArray() );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的压缩率大约是 4,或者如果我有 1024 …

compression sql-server-2012 sql-clr

6
推荐指数
1
解决办法
2662
查看次数

有没有办法让 sql server 在当前的 SQLCLR 存储过程之前搜索 master 数据库?

对于带有前缀 sp_ 的 T-SQL 存储过程,SQL Server 将在 master 数据库中搜索并使用当前过程之前的过程。对于我使用 Visual Studios 内置部署使用 SQL Server 2010 创建的 SQLCLR 存储过程,情况似乎并非如此。数据库服务器是 SQL Server 2008 R2 (SP1)。

我执行这个脚本:

SELECT name
from master.sys.procedures
WHERE type_desc='CLR_STORED_PROCEDURE' and schema_id = 1

USE tempdb
PRINT 'USING tempDb'
EXEC sp_RAISERROR_CaughtDemo;
GO
USE master
PRINT 'USING master'
EXEC sp_RAISERROR_CaughtDemo
GO
--SELECT * from sys.assembly_modules
Run Code Online (Sandbox Code Playgroud)

并且存储过程只会使用来自 master 数据库的非限定名称执行:

name
----------------------------------
sp_RAISERROR_CaughtDemo
sp_RAISERROR_UncaughtDemo

(2 row(s) affected)

USING tempDb
Msg 2812, Level 16, State 62, Line 5
Could not find stored procedure 'sp_RAISERROR_CaughtDemo'. …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-clr

5
推荐指数
1
解决办法
902
查看次数

在 SQL Server 脚本中调用 .NET 方法

在数据迁移过程中,我需要在写入目标表之前转换来自源系统的一些列值。

我已经获得了一个 Csharp 代码,它读取一个字符串并进行转换(这是一个复杂的字符串操作),然后返回转换后的字符串。

将此代码插入数据迁移 SQL 脚本的最佳方法是什么?我对 CSahrp 编程知之甚少,在研究了不同的站点后,发现这可以通过在 SSIS 包中添加脚本组件或将 .net 代码包装在可从 SQL Server 调用的 CLR 函数中来完成。

由于我的脚本不是 SSIS 包的一部分,我的偏好是定义一个 CLR 函数,但是可以吗?每个选项的优缺点是什么?

你还认为这个目标可以使用另一种更容易实现和维护的技术来实现吗?

如果你知道一个很好的链接,它会一步一步地向我展示这个过程,请与我分享:)

谢谢你。

sql-server ssis sql-server-2008-r2 sql-clr

5
推荐指数
1
解决办法
1815
查看次数

为反向 DNS 查找建议更好的设计模式

我正在处理一个项目,我需要查找与记录发出 HTTP 请求的 IP 地址关联的主机名。查找目前作为日常 ETL 工作的一部分发生。当前的方法是使用标量 CLR 函数(与此类似的代码发布在网络上的许多地方,下面发布了我的修订;我不确定原作者是谁):

using System.Data.SqlTypes;
using System.Net;
using System.Security;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Server;

public partial class udfn_GetHostName
{

[Microsoft.SqlServer.Server.SqlFunction]
public static string udfn_GetHostname(string IPAddr)
{
    try
    {
        /* 
         Using deprecated method intentionally.
         GetHostEntry() is now recommended.
         But it does some irritating things like returning an error if a PTR
         record points to a name that doesn't have an A record.
        */
        IPHostEntry IpEntry = Dns.GetHostByAddress(IPAddr);
        // Test whether the record returned has at least …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2008-r2 dns sql-clr

5
推荐指数
1
解决办法
981
查看次数

在 SQL Server 2012 中的 TSQL 函数中使用 XSD 验证 XML?

我需要在 TSQL 中使用 XSD 验证 XML。为了使此任务半自动化,我需要在 TSQL 函数中执行此操作。

为了进行验证,我必须将值设置为 XML,如果它无效,我将收到一个错误。

我的问题是在 TSQL 函数内部我不能使用TRY / CATCH. 这是正确的方式吗,如果有可能做到这一点?

xml t-sql sql-server-2012 functions sql-clr

5
推荐指数
1
解决办法
917
查看次数

将 .Net 程序集添加到 SQL CLR,而不打开 TRUSTWORTHY

我正在尝试使用 Solomon Rutzky 在其后程序集部署中提供的指导来添加“System.Messaging.dll”,并使用非对称密钥使用 UNSAFE 或 EXTERNAL_ACCESS 权限,但我在第一个障碍上失败了。

脚本的第一部分是从程序集创建证书;

CREATE CERTIFICATE [MS.NETcer] FROM EXECUTABLE FILE = 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll';
GO
Run Code Online (Sandbox Code Playgroud)

但是,当我执行此操作时,我收到错误;

Msg 15208, Level 16, State 1, Line 1
The certificate, asymmetric key, or private key file does not exist or has invalid format.
Run Code Online (Sandbox Code Playgroud)

我用来执行命令的帐户具有“sysadmin”服务器角色。这是在 SQL Server 2008 实例上。

请问有人对为什么失败有任何想法吗?

---------- 更新 1 -----------

我采纳了所罗门的建议并修改了我的脚本,使其看起来像这样;

CREATE ASYMMETRIC KEY [Key.System.Messaging] FROM EXECUTABLE FILE = 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll';
GO

CREATE LOGIN [CLR.Login.System.Messaging] FROM ASYMMETRIC KEY [Key.System.Messaging];
GO

GRANT UNSAFE ASSEMBLY TO [CLR.Login.System.Messaging];
GO
Run Code Online (Sandbox Code Playgroud)

到目前为止一切都很好。我现在运行 …

sql-server-2008 sql-server best-practices sql-clr signature

5
推荐指数
1
解决办法
4100
查看次数

Azure SQL 托管实例上的 CLR 存储过程在执行时出错:“主机存储中的程序集与 GAC 中的程序集具有不同的签名”

我有一个 CLR 存储过程,它在从 SQL Server 2012 - 2017 部署到本地 SQL Server 实例时可以正确执行。我可以成功部署到 Azure SQL 托管实例,但是当我执行该过程时,出现以下错误:

无法加载文件或程序集“System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或其依赖项之一。主机存储中的程序集与 GAC 中的程序集具有不同的签名。(来自 HRESULT 的异常:0x80131050)。

我曾尝试使用项目引用但无济于事 -System.Net.Http.dll可以部署到托管实例的唯一版本是执行时出错的版本。

sql-server sql-clr azure-sql-managed-instance

5
推荐指数
1
解决办法
949
查看次数

SQL Server CLR 函数中的 System.Web

我对这个主题做了一些简单的研究,我想知道什么是所有的优点和缺点,或者在 SQL Server 中启用/注册这个特定的 .dll?

返回信息 - 我们正在与第三方应用程序集成(不幸的是,这不是我的决定),它需要这个 .dll 来处理其他一些 .dll。我需要 CLR 函数的目的是能够在 SSMS 中编写 SQL 查询并将该数据发送到第三方应用程序的 API,然后第三方应用程序的 API 将依次执行正确的数据加载/更改(向/从该应用程序插入和删除)将通过其 API 完成)。

编辑 - 也许我应该包括这个细节

在尝试注册我的 c# 类时,我显然收到了错误“system.web 未注册等等等等”,这反过来又促使我对这个主题进行研究。

结束编辑

所以,我的难题是,为了能够注册我的 C# 类/.dll,我必须注册所有依赖的 .dll,但是根据我的研究,我知道这个特定的可能会有很大的问题。

因此,看到我对谷歌研究之外的陷阱并不十分熟悉,我想知道你们中的一个好人是否可以帮助我了解如何在这方面做出最佳决定。

另外,我还能在这篇文章中添加什么,以便更容易提供洞察力?我不太确定 C# 代码是否相关?我知道这可能有点宽泛,但我希望它足够具体而不会被标记?

更具体地说明这里发生的事情(根据所罗门的要求)

  1. 第 3 方应用程序使用“API”(松散使用,因为我被告知它不是一个很好的 API)来回发送数据。您会注意到它调用了一个 Importer 函数,该函数只接受它转换的数据表或 excel 文件。我别无选择,因为公司告诉我通过普通 XML 插入和删除非常慢并且有意外行为。

  2. 引用 System.Web 的 .DLL 在我的 C# 类中被引用,这是首先需要能够向它发送数据的。

  3. 关于:

    为什么你不能使用我提到的方法?它们已经存在于 SQL Server 的 CLR 主机中。这是一个网络服务,对吧

我不确定我对 API 的总体了解是否足以回答这个问题。我很愿意而且只是缺乏这样做的知识和经验。这也可能是因为我对如何与这个特定的 API 交互有限制,我不确定这些限制如何应用于这些方法。(我会进一步调查,看看我是否可以自己回答这个问题)。

尽管我考虑得越多,我可以创建一个 SQL Server 可以调用的“中间人”类,然后它会调用另一个类,该类将拥有所有正确的引用,这可能会让我摆脱当前的情况。但是,我仍然对具体的反馈感兴趣,以便我可以从中学习。

这是我的 C# 类:

    using Perfion.Api;   -- this .DLL …
Run Code Online (Sandbox Code Playgroud)

sql-server c# sql-clr web-service api

5
推荐指数
1
解决办法
286
查看次数

如何在 SSDT 部署中将 CLR 程序集注册为受信任

我在 SSDT 中有 CLR 程序集,并且部署它必须是可信的。据我所知,有 4 个选项如何做到这一点

第一个选项,使用 TRUSTWORTHY

EXEC sp_configure 'clr enabled', 1;  
RECONFIGURE;  
  
ALTER DATABASE SourceDatabase SET TRUSTWORTHY ON;
Run Code Online (Sandbox Code Playgroud)

第二个选项,禁用严格安全性

EXEC sp_configure 'clr enabled', 1;  
RECONFIGURE;  
  
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;

EXEC sp_configure 'clr strict security', 0;
RECONFIGURE;
Run Code Online (Sandbox Code Playgroud)

第三个选项,使用密钥或证书对程序集进行签名

Seems complicated and I was not able to manage that yet. I will appreciate the instructions, because the workflow is not clear here.
Run Code Online (Sandbox Code Playgroud)

第四个选项,使用sp_add_trusted_assembly

EXEC sp_configure 'clr enabled', 1;  
RECONFIGURE;

declare @assembly varbinary(max) = 0x4D5A90000300000004000000FFFF0000... -- …
Run Code Online (Sandbox Code Playgroud)

deployment sql-clr ssdt sql-server-2017

5
推荐指数
1
解决办法
7764
查看次数