【问题标题】:CLR SplitString Exception while executing in SQL Server在 SQL Server 中执行时出现 CLR SplitString 异常
【发布时间】:2021-03-04 19:28:51
【问题描述】:

您好,我是 C# 编程新手,刚刚从 @Aaronaught's answer 复制并粘贴了 CLR 函数,以便在 SQL Server 2012 中使用它:

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

public class CustomFunctions
{
    [
        Microsoft.SqlServer.Server.SqlFunction
        (
            FillRowMethodName = "FillRow",
            TableDefinition = "nRow int, string nvarchar(4000)"
        )
    ]
    public static IEnumerable SplitString(SqlString str, SqlString delimiter)
    {
        if (str.IsNull || delimiter.IsNull)
        {
            return null;
        }

        string[] values = str.Value.Split(delimiter.Value.ToCharArray());

        StringPair[] results = new StringPair[values.Length];

        for (int i = 0; i < values.Length; i++)
        {
            results[i] = new StringPair(i + 1, values[i]);
        }
        return results;
    }

    public static void FillRow(object row, ref int id, ref string value)
    {
        StringPair pair = (StringPair)row;
        id = pair.ID;
        value = pair.Value;
    }

    public class StringPair
    {
        public StringPair(int id, string value)
        {
            this.ID = id;
            this.Value = value;
        }

        public int ID { get; private set; }
        public string Value { get; private set; }
    }
};

我编译为汇编:

sp_configure 'show advanced options', 1
RECONFIGURE
GO
sp_configure 'clr enabled', 1
RECONFIGURE
GO
sp_configure 'show advanced options', 0
RECONFIGURE
GO

CREATE ASSEMBLY [CustomFunctionsC]
FROM 'C:\custom\CustomFunctions\CustomFunctionsC.dll'
WITH PERMISSION_SET = SAFE
GO

IF OBJECT_ID('[dbo].[SplitString]') IS NOT NULL
DROP FUNCTION [dbo].[SplitString]
GO
CREATE FUNCTION [dbo].[SplitString](@string_in [nvarchar](4000), @delimiter [nvarchar](4000))
RETURNS  TABLE (
    nRow    INT,
    string  NVARCHAR(4000) NULL
) WITH EXECUTE AS CALLER
AS 
EXTERNAL NAME [CustomFunctionsC].[CustomFunctions].[SplitString]
GO

然后我在 SQL Server 中执行它:

DECLARE @string VARCHAR(256) = '1,2,3,4,5,6,7';

SELECT * FROM [dbo].[SplitString](@string, ',')

抛出异常 System.ArgumentNullException:

System.ArgumentNullException:值不能为空。参数名称: ptr System.ArgumentNullException:在 System.Runtime.InteropServices.Marshal.PtrToStringUni(IntPtr ptr, int32 长度)

由于我无法在当前环境中调试 CLR 函数,我什至不知道哪一行会引发该异常。

【问题讨论】:

标签: c# sql sql-server clr argumentnullexception


【解决方案1】:

也许不是您正在寻找的答案,但为什么不制作一个本机 sql 函数来做到这一点呢?它会更便宜,性能也会更好,这是一种方法:

CREATE or alter FUNCTION STRING_SPLIT2
(
  @List      nvarchar(max),
  @Delimiter nchar(1)
)
RETURNS @t table (Item nvarchar(max))
AS
BEGIN
  SET @List += @Delimiter;
  ;WITH a(f,t) AS  
  (
    SELECT CAST(1 AS bigint), CHARINDEX(@Delimiter, @List)
    UNION ALL
    SELECT t + 1, CHARINDEX(@Delimiter, @List, t + 1) 
    FROM a WHERE CHARINDEX(@Delimiter, @List, t + 1) > 0
  )  
  INSERT @t SELECT SUBSTRING(@List, f, t - f) FROM a OPTION (MAXRECURSION 0);
  RETURN;  
END
GO  

如果你在SQL Server 2017或以上,SQL server 有内置函数 称为“STRING_SPLIT”,做同样的事情:

DECLARE @string VARCHAR(256) = '1,2,3,4,5,6,7';

SELECT * FROM string_split(@string, ',')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2012-04-19
    • 2017-08-02
    • 2016-03-31
    • 1970-01-01
    相关资源
    最近更新 更多