2

我正在寻找一个与 C# 中的 String.Format 执行相同操作的 CLR 函数。例如,我想通过 CLR 函数执行以下操作:

String.Format("My name is {0}, and I live in {1}",myName, cityName)

我希望能够在第一个参数之后传递可变数量的参数,这将与在此 CLR 函数的第一个参数中指定的占位符一样多。任何人都知道这样的 CLR 函数的 C# 代码是什么?

4

1 回答 1

1

我正在寻找同样的东西。我遇到了这两个网站:http ://www.fotia.co.uk/fotia/Blog/2009/05/indispensable-sql-clr-functions.html & http://stringformat-in-sql.blogspot.com /

第一个使用 CLR 函数,另一个使用存储过程。

在第一篇文章中,作者说 UDF 参数不是可选的,因此您不能拥有可变数量的参数(至少他这样做的方式)。他只是用他需要的数字或参数创建一个不同的函数。

[SqlFunction(DataAccess = DataAccessKind.None)]
public static SqlString FormatString1(SqlString 格式,对象 arg0,对象 arg1)
{
   返回格式。IsNull ?SqlString.Null :
       string.Format(format.Value, SqlTypeToNetType(arg0, arg1));
}



编辑: 这就是我为我解决这个问题的方法。

使用第二篇文章中的存储过程,我创建了这个函数来使用数据透视表为我设置文本格式。我们的数据库设置有一个表dbo.[Rules],该表的列[Description]具有需要格式化的字符串,例如:“NET INCOME MARGINAL (${0} TO BELOW ${1})”。然后我们有一个 1-many 表dbo.[RuleParameters],其中每个需要替换的值都有一行。该列dbo.[SortOrder]指定参数进入的顺序。此函数将适用于我们拥有的最多 4 个参数。

CREATE FUNCTION [dbo].[GetRuleDescriptionWithParameters]
(
    @Code VARCHAR(3)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @Result NVARCHAR(400)

    SELECT 
        @Result =
            dbo.FormatString([Description], 
                ISNULL([1], '') + ',' + 
                ISNULL([2], '') + ',' + 
                ISNULL([3], '') + ',' + 
                ISNULL([4], '')
                )
    FROM
    (
        SELECT 
        r.[Description]
        ,rp.Value
        ,rp.SortOrder

        FROM 
            [Rules] r
        LEFT OUTER JOIN [RuleParameters] rp
            ON r.Id = rp.RuleId

        WHERE r.Code = @Code

    ) AS SourceTable
    PIVOT
    (
        MAX(Value)
        FOR SortOrder IN ([1], [2], [3], [4])
    ) AS PivotTable;


    RETURN @Result
END

编辑#2:添加更多示例

格式化字符串函数:

CREATE FUNCTION [dbo].[FormatString]
(
    @Format NVARCHAR(4000) ,
    @Parameters NVARCHAR(4000)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @Message NVARCHAR(400),
@Delimiter CHAR(1)
DECLARE @ParamTable TABLE ( ID INT IDENTITY(0,1), Paramter VARCHAR(1000) )
SELECT @Message = @Format, @Delimiter = ','
;WITH CTE (StartPos, EndPos) AS
(
    SELECT 1, CHARINDEX(@Delimiter, @Parameters)
    UNION ALL
    SELECT EndPos + (LEN(@Delimiter)), CHARINDEX(@Delimiter,@Parameters, EndPos + (LEN(@Delimiter)))
FROM CTE
WHERE EndPos > 0
)
INSERT INTO @ParamTable ( Paramter )
SELECT
[ID] = SUBSTRING ( @Parameters, StartPos, CASE WHENEndPos > 0 THEN EndPos - StartPos ELSE 4000 END )
FROM CTE
UPDATE @ParamTable SET @Message = REPLACE ( @Message, '{'+CONVERT(VARCHAR,ID) + '}',     Paramter )
RETURN @Message
END
GO

这是我调用存储过程的方式:

SELECT r.[Id]
        ,[Code]
        ,[Description]
        ,dbo.GetRuleDescriptionWithParameters([Code])
        ,rp.[Value]
        ,rp.SortOrder
FROM [Rules] r
INNER JOIN [RuleParameters] rp
    ON r.Id = rp.RuleId

现在我可以像这样调用函数来为我格式化所有内容!这是带有结果的示例用法:

Id  Code    Description                     (No column name)          Value     SortOrder
1   1       NOT THE MINIMUM AGE             NOT THE MINIMUM AGE       18        1
3   8       NET INCOME (BELOW ${0})      NET INCOME (BELOW $400)   400    1
4   9       NET (${0} TO BELOW ${1})          NET ($400 TO BELOW $600)  400         1
4   9       NET (${0} TO BELOW ${1})          NET ($400 TO BELOW $600)  600         2

通常在调用它时,我不会加入 [RuleParameters] 表,但在这种情况下我这样做是为了让您可以在一个数据集中查看前后的数据。

于 2012-11-06T21:42:22.090 回答