AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 252077
Accepted
Doug Coats
Doug Coats
Asked: 2019-10-29 06:06:06 +0800 CST2019-10-29 06:06:06 +0800 CST 2019-10-29 06:06:06 +0800 CST

SQL Server CLR 函数中的 System.Web

  • 772

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

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

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

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

结束编辑

所以,我的难题是,为了能够注册我的 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 references System.Web. 
    using Perfion.Api.Import;
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;

    namespace PerfInsert
    {
        public static class PerfionInsert 
        {
            public static bool CreateCommand(string tblString, string featureName, string connectionString, string perfionConnectionString, string logFile)
            {
                StringBuilder logInfo = new StringBuilder();
                try
                {
                    var wList = new Regex(@"[^0-9a-z\.\[\]_]#", RegexOptions.IgnoreCase);
                    if (wList.IsMatch(tblString))
                    {
                        logInfo.AppendLine($"{DateTime.UtcNow} - Regex Validation Failed for Table Name!");
                        return false;
                    }
                    using (SqlConnection connection = new SqlConnection(connectionString))
                    {
                        var qryString = "SELECT * FROM " + tblString;
                        using (SqlCommand command = new SqlCommand(qryString, connection))
                        {
                            connection.Open();
                            using (var dataReader = command.ExecuteReader())
                            using (var dataTable = new DataTable())
                            {
                                dataTable.Load(dataReader);
                                PerfionApi api = new PerfionApi(perfionConnectionString);
                                Importer importer = new Importer(api.Connection);
                                importer.Status += (sender, e) => { logInfo.AppendLine($"{DateTime.UtcNow} - {e.Title}"); };
                                importer.LoadData(dataTable);
                                importer.ImportToDatabase(featureName);
                            }
                        }
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    logInfo.AppendLine($"{DateTime.UtcNow} - {ex.ToString()}");
                }
                finally
                {
                    File.AppendAllText(logFile, logInfo.ToString());
                }
                return false;
            }
        }
    }
sql-server c#
  • 1 1 个回答
  • 444 Views

1 个回答

  • Voted
  1. Best Answer
    Solomon Rutzky
    2019-10-29T06:37:42+08:002019-10-29T06:37:42+08:00

    3rd 方软件需要 DLL 在这里似乎无关紧要。看来问题很简单:

    我需要...能够在 SSMS 中编写 SQL 查询并将该数据发送到第三方应用程序的 API,然后它会执行正确的数据加载/更改(必须在此应用程序中插入和删除)通过其 API 完成)。

    我相信你最好的两个选择是:

    1. 如果此过程如您所说的那样简单,并且您真的想坚持使用System.Web,那么为什么不创建一个控制台应用程序来执行查询,然后将您需要的任何内容发布到 API 中呢?如果需要定期执行此操作,可以在 Windows 任务计划程序或 SQL Server 代理中进行计划(通过“操作系统 (CmdExec)”作业步骤)。

    2. 如果此过程稍微复杂一些和/或您需要能够以更动态/特别的方式执行这些查询,则System.Web不需要,它只是使一些编码更容易。Intead,查看HttpWebRequest和HttpWebResponse。这两个包含在 中System.Net,这是 SQLCLR 支持的 .NET Framework 库之一。主要区别在于您需要手动构建 XML 请求。处理响应也是如此。这种方法比导入更稳定和安全System.Web。

      按照这些思路,对于任何需要此类功能但不想(或不能)对其进行编码的人,我编写了一个 SQLCLR 函数和过程库 — SQL# — 其中包括一个存储过程INET_GetWebPages,它实现了这两种方法。虽然有免费版本,但此特定存储过程仅在完整(即付费)版本中可用。但是,它确实处理了各种选项/场景,包括:设置各种 HTTP 标头、可选的基本身份验证、代理服务器、发送 GET 与 POST 数据、处理 PUT 请求以及减少对性能的潜在负面影响的选项。

    如果您说您正在使用 3rd 方应用程序的 DLL 通过他们提供的方法进行 API 调用,并且引用和使用的是他们的 DLL System.Web(而不是您的代码直接),那么很难完全肯定地说所有的影响都是。但这里有一些关于这种方法需要考虑的事情:

    System.Web不在SQLCLR支持的 .NET Framework 库列表中。这至少意味着:

    1. 不保证此库可在 SQL Server 中加载。即使当前可以加载,SQL Server 也只允许纯 MSIL 库,并且不会加载混合模式库(即其中包含托管和非托管代码的 DLL)。没有办法绕过这个限制。由于此库不在列表中,因此它可以在未来的 .NET Framework 更新中从纯更改为混合。如果发生这种情况,此代码将停止工作,因为这是一个框架库并已加载到 GAC 中,并且加载到 SQL Server 和 GAC 中的库必须是完全相同的版本(因此您不能继续使用旧的工作版本) . 这种从纯到混合的变化并不经常发生,但以前发生过。
    2. 这个库需要加载为UNSAFE. 这本质上不是问题,但确实允许很容易成为问题的行为。例如,如果此第 3 方 DLL 使用的任何代码路径使用静态变量来缓存信息,如果该值不是标准的(即它可以在调用此代码之间甚至期间更改),那么您可以由于 SQL Server 使用共享的应用程序域并且所有会话共享相同的内存/静态数据,因此进入竞争状态。

    UNSAFE由于不在“支持”列表中,因此必须加载一些代码,并且它包含违反安全策略的内容,即使您永远不会使用该特定代码路径。在这些情况下,代码在技术上可以是“安全的”,但如果没有看到源代码,你就无法确定。所以你需要测试,但测试需要超过 1 个人点击几次:它需要多个并发会话点击此代码以查看是否存在竞争条件。但是还有其他更难测试的场景,例如由于异常导致的内存泄漏。受支持的库中的某些方法因此受到限制,但可能没有人知道不受支持的库中的方法是否存在此类问题,因为我不相信它们已经过测试。

    如果此功能旨在非面向用户(即系统进程、公司内部功能等),那么您可以通过启动 SQL Server Express 实例并加载来缓解大多数问题(安全性、性能、稳定性)你在那里的项目。这会将非理想 SQLCLR 功能与您的生产应用程序隔离/隔离。假设您已经在使用常规的外部SqlConnection(不是内部/受信任的连接),那么这不需要对您的代码进行任何更改。

    使用这种方法(即,将 SQLCLR 项目加载到隔离实例中)无法减轻的唯一风险是,如果 Microsoft 更新System.Web(或将其加载到 SQL Server 时被吸入的任何依赖项),代码可能会中断是一个混合模式库。这可能永远不会发生,但如果发生了,那么除非他们切换到 using ,否则您将无法加载该 3rd 方 DLL HttpWebRequest,而且他们几乎没有理由进行此类更改。

    更新

    OP 回复了一个相关问题,他们选择将项目类型更改为控制台应用程序,并且最有可能使用 SQL 代理来安排它(但也可以使用 Windows 任务计划程序

    相关文章(在 StackOverflow 上):

    1. CREATE PROCEDURE 为 SQLCLR 存储过程获取“消息 6567,级别 16,状态 2”
    2. 带有 CLR 函数的 System.Security.SecurityException
    • 7

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve