I know the use of a static variable in your DLL is unsafe, but is there any way to have something similar, or a variable that only exists for the current context?
What I'm trying to do is create a UDF which takes a comma-separated string, and returns a table with two columns, one is the index/order of the value in the original string, the other is the value itself. The splitting is easy (there's plenty of examples on-line, my code is below), but getting the order seems impossible.
I've tried using an IDENTITY column, but they're disallowed ("Cannot use 'IDENTITY' column in the result table of a streaming user-defined function"), and using a static vaiable is a no-go. In a web project, you get System.Web.HttpContext.Current, is there anything similar for a SQL project? Or is there a better way to do what I'm looking for?
SQL
CREATE FUNCTION SplitToInt(@list nvarchar(MAX), @delim nchar(1) = N',')
RETURNS TABLE (Value int)
AS EXTERNAL NAME CompanyName.Functions.SplitToInt
GO
C#
[SqlFunction(FillRowMethodName = "SplitToIntFillRow")]
public static IEnumerable SplitToInt(SqlString str, SqlString separator)
{
return str.Value.Split(!separator.IsNull && separator.Value.Length > 0 ? separator.Value[0] : ',');
}
public static void SplitToIntFillRow(object row, out int Value)
{
Value = System.Convert.ToInt32((string)row);
}
My solution (funny how writing things down, walking away, and coming back makes you see the obvious)
SQL
CREATE FUNCTION SplitToInt(@list nvarchar(max), @separator nchar(1) = N',')
RETURNS TABLE (InLevelOrder int, Value int)
AS EXTERNAL NAME CompanyName.Functions.SplitToInt
GO
C#
[SqlFunction(FillRowMethodName = "SplitToIntFillRow")]
public static IEnumerable SplitToInt(SqlString str, SqlString separator)
{
var s = str.Value.Split(!separator.IsNull && separator.Value.Length > 0 ? separator.Value[0] : ',');
var rtn = new List<int[]>(s.Length);
for (int i = 0; i < s.Length; i++)
rtn.Add(new[] { i, System.Convert.ToInt32(s[i]) });
return rtn;
}
public static void SplitToIntFillRow(object row, out int InLevelOrder, out int Value)
{
InLevelOrder = ((int[])row)[0];
Value = ((int[])row)[1];
}
If anyone can improve on this, feel free to comment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With