标签: sqlclr

为什么 SQL Server 不会将我的程序集注册为 SAFE?

在 SQL Server 2008 上,我试图注册一个似乎只引用受支持库的程序集。这是我用来注册程序集的 T-SQL 代码:

create assembly MySpatial from 'c:\Spatial.dll'
Run Code Online (Sandbox Code Playgroud)

这会导致以下错误:

消息 6509,级别 16,状态 31,第 1 行从具有 HRESULT 0x80004005 的程序集“空间”收集元数据时出错。

但是,如果我添加with permission_set=unsafe,那么 SQL 将成功执行该命令。如何找出错误发生的原因,或者为什么我的程序集必须注册为不安全?

sql-server sqlclr

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

索引如何在 SQL 用户定义类型 (UDT) 上工作?

这已经困扰我一段时间了,我希望 SQL Server 专家之一能够对此进行一些说明。

问题是:

当您对包含 UDT(CLR 类型)的 SQL Server 列建立索引时,SQL Server 如何确定对给定查询执行什么索引操作?

具体来说,我想到的是hierarchyid(AKA SqlHierarchyID)类型。Microsoft 建议您使用它的方式 - 以及我使用它的方式 - 是:

  • 在列本身上创建一个索引hierarchyid(我们称之为ID)。这可以实现深度优先搜索,因此当您编写 时WHERE ID.IsDescendantOf(@ParentID) = 1,它可以执行索引查找。

  • 创建持久计算Level列并在 上创建索引(Level, ID)。这启用了广度优先搜索,因此当您编写 时WHERE ID.GetAncestor(1) = @ParentID,它可以为此表达式执行索引查找(在第二个索引上)。

但我不明白的是,这怎么可能? 它似乎违反了正常的查询计划规则 - 对GetAncestor和 的调用IsDescendantOf似乎不可控制,因此这应该会导致完整索引扫描,但事实并非如此。显然,我并不是在抱怨,而是我试图了解是否可以在我自己的 UDT 上复制此功能。

难道hierarchyidSQL Server有一种特殊的感知能力,如果它发现查询元素和索引的某种组合,就会自动改变执行计划吗?或者 CLR 类型是否只是定义 SQL Server 引擎可以理解的SqlHierarchyID特殊属性/方法(类似于持久计算列的工作方式)?IsDeterministic

我似乎找不到任何有关此的信息。我所能找到的只是一段文字,指出该IsByteOrdered属性通过保证每个实例有一个唯一的表示来使索引和检查约束之类的事情成为可能;虽然这有点有趣,但它并没有解释 SQL Server 如何使用某些实例方法执行查找。 …

sql-server clr performance sqlclr sql-server-2008

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

如何为SQL CLR存储过程提供sql_variant参数?

如何将sql_variant参数添加到SQL CLR存储过程?使用System.Object不起作用,我没有看到任何可以使用的属性.

[Microsoft.SqlServer.Server.SqlProcedure]
public static void ClearOnePartition(
    SqlString aString
    , /* I want this to be a sql_variant */ object aVariant
)
{
    //do stuff here
}
Run Code Online (Sandbox Code Playgroud)

c# sql sql-server stored-procedures sqlclr

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

如何正确序列化可排序的SQLCLR用户定义类型?

我在C#中构建自定义用户定义类型以与SQL CLR一起使用.请参阅此参考.

底层数据可以使用常规带符号的32位整数以4个字节表示.这是实施:

[Serializable]
[SqlUserDefinedType(Format.UserDefined, IsByteOrdered = true,
                    IsFixedLength = true, MaxByteSize = 4)]
public struct MyUDT : INullable, IBinarySerialize
{
    private int _value;

    public int Value
    {
        get { return _value; }
    }

    public MyUDT(int value)
        : this()
    {
        _value = value;
    }

    public override string ToString()
    {
        return _value.ToString(CultureInfo.InvariantCulture);
    }

    [SqlMethod(OnNullCall = false)]
    public static MyUDT Parse(SqlString s)
    {
        int i = int.Parse(s.Value);
        return new MyUDT(i);
    }

    public bool IsNull { get; private set; }
    public …
Run Code Online (Sandbox Code Playgroud)

.net c# sql-server sorting sqlclr

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

SQL Server 在哪里存储部署的 CLR 程序集?

我创建了一个 SQL CLR 用户定义的函数并将其部署到 SQL Server 实例上的数据库中,在那里它可以正常工作。

SQL Server 在哪里存储部署的 CLR 程序集?它们存储在文件系统的某个地方吗?

c# sql-server sqlclr

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

如何通过 SqlDataReader 获取结果集中字符串字段的排序规则?

SqlDataReader检索结果集时,可以使用GetSchemaTable方法获取该结果集的大部分元数据。然而,缺少的一件事是字符串字段的排序规则(即CHAR, VARCHAR, NCHAR, NVARCHAR, SQL_VARIANT– 如果包含字符串类型 – 甚至不推荐使用的TEXTNTEXT)。有什么办法可以得到这些信息吗?

虽然在技术上可以调用具有和属性的GetSqlString方法,但这些属性返回与数据库的默认排序规则相关的值,这可能是也可能不是任何特定字段的排序规则(即使大多数人似乎只是假设它是相同的)或表达式(由于Collat​​ion Precedence)。这些属性仅在源数据类型为 时才提供准确信息,这并不是很有帮助。LCIDSqlCompareOptionsSQL_VARIANT

没有这些额外信息(至少相当于 Locale 的“LCID”)的问题是,虽然所有字符,无论源编码如何,都可以在 .NET 中表示而不会丢失(因为 .NET 字符串是 UTF- 16 Little Endian),在将结果集中的字段与其他字符串进行比较时,无法确定要使用的 Locale。

每个字符串字段的排序规则信息绝对是通过 TDS 流从 SQL Server 发送到客户端的结果集元数据的一部分。它用于:

  • LCID通过类的GetLocaleId方法公开SqlDataReader。但是该方法已被标记,internal因此我无权访问它。它似乎只在一个地方使用:SqlBulkCopy
  • 向 的Send(SqlDataReader)方法提供结果集结构,该方法SqlPipe用于 SQLCLR 存储过程和触发器。
  • encoding根据情况在 的GetTextReader()方法中设置适当的SqlDataReader。但是,虽然该方法是public …

.net sql-server sqlclr sqldatareader collation

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

如何允许 SQL CLR 函数在并行查询计划中运行并具有数据访问权限

我编写了许多 SQL CLR 函数 (UDF),它们从托管在 IBM iSeries 上的外部 DB2 数据库(使用 IBM DB2 .Net Provider)读取数据。为了使函数具有读取此数据的必要权限,我需要使用 SqlFunction 属性装饰该函数,并将 DataAccess 属性设置为 DataAccessKind.Read。我还将程序集部署为 UNSAFE。

从 DB2 数据库读取数据所花费的时间相对较慢(例如,最简单的 ExecuteScalar 需要 3 毫秒)。

我使用这些 UDF 有效地将 DB2 数据库中的数据合并到 Sql Server 视图中。

例如,假设我的 UDF 定义为

[SqlFunction(DataAccess = DataAccessKind.Read, IsDeterministic = true)] 
public static SqlMoney GetCostPrice(SqlString partNumber)
{
    decimal costPrice;
    // open DB2 connection and retrieve cost price for part
    return new SqlMoney(costPrice);
}
Run Code Online (Sandbox Code Playgroud)

然后在我的 SQL 视图中使用它作为:

select Parts.PartNumber,
       dbo.GetCostPrice(Parts.PartNumber) as CostPrice
from Parts
Run Code Online (Sandbox Code Playgroud)

如果我可以使用并行查询计划运行我的 SQL 视图,那么糟糕的性能问题可能会受到显着影响。

有关于如何强制查询计划并行而不是串行运行的文档技术,但这些技术受到 …

.net sql-server sqlclr code-access-security elevated-privileges

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

如何将旧的 Visual Studio 项目迁移到 Visual Studio 2017?

目标: 我尝试使用 Pluralsight课程中的SQL Server 的 CLR 代码打开一个 Visual Studio 项目 (c#) 。

问题:在 Visual Studio 2017 上进行单向升级 后,我没有收到错误消息,只是收到以下警告。

您的项目面向 .NET Framework 2.0 或 3.0。如果您的项目使用需要更新的 .NET Framework 的程序集,您的项目将无法生成。您可以通过单击项目菜单上的属性,然后在“.NET Framework”下拉框中选择新版本来更改 .NET Framework 版本。(在 Visual Basic 中,它位于“编译”选项卡上,单击“高级编译器选项...”按钮。)

  • 当我打开一个包含单个项目的解决方案时,我收到以下消息

项目需要迁移

或者

项目需要加载

在此处输入图片说明

尝试过: 我尝试使用较新/较旧版本编辑 csproj 文件。我使用 Visual Studio 2017 和 Visual Studio 2015 尝试了不同的 PC

想法:安装 Visual Studio 2010,因为课程于 2010 年发布,但我真的不想要那样。

migration sqlclr visual-studio

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

如何对我正在使用的不安全的 C# CLR 和程序集进行签名,而不是将数据库放在可信的位置上

我在我的 C# CLR 代码中使用 .NET DirectoryServices 和 DirectoryServices.AccountManagement。我想发布到我的 SQL Server 数据库作为一个不安全的 CLR 存储过程。在 Visual Studio 中,我签署了我的 CLR 项目。我想避免打开“值得信赖”。我还如何签署程序集?我知道这听起来很简单,但我在谷歌上搜索了 4 个小时却没有找到答案。当我将 Stairway 下载到 CLR 时,我以为我已经很接近了,但在那里找不到答案。

.net c# unsafe sqlclr visual-studio

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

Microsoft.SqlServer.Server 命名空间

我正在尝试实现与 SQL Server 一起使用的公共语言运行时 (CLR) 程序集。为了创建 dll,我使用的是 Visual Studio 2019。

我有一个示例教程中的以下代码:

using System;
using System.Collections;
using System.Text;
using System.Data;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;


namespace Split
{
    public class Class1
    {
        [SqlFunction(
            DataAccess = DataAccessKind.None,
            FillRowMethodName = "MyFillRowMethod"
            , IsDeterministic = true)
        ]

        public static IEnumerable Split(string stringToSplit, string delimiters)
        {

            string[] elements = stringToSplit.Split(delimiters.ToCharArray());
            return elements;
        }

        public static void MyFillRowMethod(Object theItem, out SqlChars results)
        {
            results = new SqlChars(theItem.ToString());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我遇到了这个错误:

错误 CS0234 命名空间“Microsoft”中不存在类型或命名空间名称“SqlServer”(您是否缺少程序集引用?)

有人可以告诉我解决问题的方法吗?

c# sql-server sqlclr

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