Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6064183
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T09:15:09+00:00 2026-05-23T09:15:09+00:00

Can anyone skilled in t-sql create companion table-valued functions to these C# array pack

  • 0

Can anyone skilled in t-sql create companion table-valued functions to these C# array pack & unpack utility methods that escape delimiters and preserve nulls, null arrays, empty arrays through roundtrip encoding?

By packing any variety of string arrays into a string, you can pass such (small) arrays to SQL as parameters, which is useful in some scenarios.

static class ArrayUtil
{
    public static string Pack(string[] original)
    {
        return Pack(original, '|', '0', '~');
    }

    public static string[] Unpack(string original)
    {
        return Unpack(original, '|', '0', '~');
    }

    public static string Pack(string[] original, char delimiter, char zed, char escape)
    {
        if (delimiter == escape ||
            zed == escape ||
            delimiter == zed) throw new ArgumentException("special characters must be distinct");

        // Null array returns a null string
        if (original == null) return null;

        // Empty array returns an empty string
        if (original.Length == 0) return string.Empty;

        // Arrays with a single empty element are represented as just the escape character
        // to differentiate from an empty array
        if (original.Length == 1 && original[0] == string.Empty) return escape.ToString();

        // Otherwise
        StringBuilder sb = new StringBuilder();

        for (int i = 0, ol = original.Length; i < ol; i++)
        {
            string s = original[i];

            if (s == null)
            {
                sb.Append(zed); // zed == null
            }
            else
            {
                for (int j = 0, sl = s.Length; j < sl; j++)
                {
                    char c = s[j];

                    // escape literal delimiters, escapes, and leading zeds
                    if (c == delimiter ||
                        c == escape ||
                        (c == zed && j == 0)) sb.Append(escape);

                    sb.Append(c);
                }
            }

            if (i != ol - 1) sb.Append(delimiter); // no trailing delimiter
        }

        return sb.ToString();
    }

    public static string[] Unpack(string original, char delimiter, char zed, char escape)
    {
        if (delimiter == escape ||
            zed == escape ||
            delimiter == zed) throw new ArgumentException("special characters must be distinct");

        // Null string returns a null array
        if (original == null) return null;

        // Empty string returns an empty array
        if (original == string.Empty) return new string[] { };

        // A single escape character represents an array with a single empty element
        // to differentiate from an empty array
        if (original == escape.ToString()) return new string[] { string.Empty };

        // Otherwise
        StringBuilder sb = new StringBuilder(); // A place to store the current element
        StringReader sr = new StringReader(original); // A stream of the original string
        List<string> unpacked = new List<string>(); // The finished elements
        int next;

        while ((next = sr.Read()) >= 0)
        {
            char c = (char)next;

            if (c == zed && sb.Length == 0)
            {
                unpacked.Add(null);

                if ((next = sr.Peek()) >= 0 && (char)next != delimiter)
                    throw new ArgumentException("An element's leading zed character must be escaped or must alone be the element", "original");

                sb = null;
            }
            else if (c == delimiter)
            {
                if (sb != null) unpacked.Add(sb.ToString());

                sb = new StringBuilder();
            }
            else if (c == escape)
            {
                if ((next = sr.Read()) >= 0)
                {
                    sb.Append((char)next);
                }
                else
                    throw new ArgumentException("Escapee expected", "original");
            }
            else
            {
                sb.Append(c);
            }
        }

        // A final zed character will make sb = null, but otherwise we have an additional element
        if (sb != null) unpacked.Add(sb.ToString());

        return unpacked.ToArray();
    }
}

Example packings with Pack(original, '|', '0', '~'), basic case:

["hello", "world"] -> "hello|world"

Some special cases (as discovered by PEX)

null -> null
[null] -> "0"
[null, null] -> "0|0"
[] -> ""
[""] -> "~"
["", ""] -> "|"
["|", "|"] -> "~||~|"
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T09:15:09+00:00Added an answer on May 23, 2026 at 9:15 am

    Here’s a stab at T-SQL Unpack:

    CREATE FUNCTION [dbo].[UnpackStrings]
    (
          @original nvarchar(4000), 
          @delimiter nchar(1),
          @zed nchar(1),
          @escape nchar(1)
    )
    RETURNS 
    @unpacked TABLE 
    (
          elementNumber INT IDENTITY(1,1), 
          element nvarchar(4000)
    )
    AS
    BEGIN
          DECLARE @next int;
          DECLARE @c nchar(1);
          DECLARE @pos int;
          DECLARE @sb nvarchar(4000);
    
          -- Special characters must be distinct.
          IF ( (@delimiter = @escape) OR 
                 (@zed = @escape) OR 
                 (@delimiter = @zed) )
                RETURN;
          -- Null string return a null array
          IF (@original IS NULL)
                RETURN;
          -- A single escape character represents an array with a single 
          -- empty element to differentiate from an empty array.
          IF (@original = @escape)
          BEGIN
                INSERT @unpacked (element) VALUES ('');
                RETURN;
          END
          -- Otherwise read through the string and unpack.
          SET @pos = 1;
          SET @sb = '';
          SET @next = 0;
          -- Fill the table variable with the rows for your result set
          WHILE(  (@pos <= LEN(@original)) AND @next IS NOT NULL )
          BEGIN
                SET @next = UNICODE(SUBSTRING(@original, @pos, 1));
                IF (@next IS NULL)
                BEGIN
                      IF (LEN(@sb) > 0)
                            INSERT @unpacked (element) VALUES (@sb);
                            SET @sb = '';
                      CONTINUE;
                END
                ELSE
                BEGIN
                      SET @c = NCHAR(@next);
                      IF ( @c = @zed AND (LEN(@sb) = 0 OR LEN(@sb) IS NULL) )
                      BEGIN
                            INSERT @unpacked (element) VALUES (NULL);
                            -- need to peek at next character,
                            SET @next = UNICODE(SUBSTRING(@original, @pos+1, 1));
                            IF (@next IS NOT NULL)
                            BEGIN
                                  SET @c = NCHAR(@next);
                                  IF ( @c != @delimiter )
                                  BEGIN
                                        -- Peek at next character and it not delimiter,
                                        -- bad format encountered.
                                        BREAK;
                                  END
                            END                     
                            SET @sb = NULL;
                      END
                      ELSE
                      BEGIN
                            IF ( @c = @delimiter )
                            BEGIN
                                  IF (LEN(@sb) > 0 )
                                        INSERT @unpacked (element) VALUES (@sb);
                                  SET @sb = '';
                            END
                            ELSE
                            BEGIN
                                  IF ( @c = @escape )
                                  BEGIN
                                        SET @pos = @pos + 1;
                                        SET @next = UNICODE(SUBSTRING(@original, @pos, 1));
                                        IF (@next IS NULL )
                                        BEGIN
                                              CONTINUE;
                                        END
                                        ELSE 
                                        BEGIN 
                                              SET @sb =  @sb +  NCHAR(@next);
                                        END
                                  END
                                  ELSE
                                  BEGIN
                                        SET @sb =  @sb + @c; 
                                  END 
                            END
                      END
                      --
                END
                SET @pos = @pos + 1;
          END   
          --
          -- Likely not needed.  This is handled above.
          --
          -- A final zed character will made sb = null,
          -- but otherwise we have an additional element.
          IF (@sb IS NOT NULL )
                INSERT @unpacked (element) VALUES (@sb);
    
          RETURN 
    END
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Can anyone suggest me a helpful programming language which can be used to create
maybe anyone can help me out with my SELECT statement on MS SQL Server.
Can anyone tell me if either of these will perform better than the other
Can anyone (maybe an XSL-fan?) help me find any advantages with handling presentation of
Can anyone tell me how I can display a status message like 12 seconds
Can anyone recommend a good library for generating an audio file, such as mp3,
Can anyone recommend some good resources that highlight the differences between Oracle and the
Can anyone point me to a good resource (or throw me a clue) to
Can anyone recommend a good binary XML format? It's for a JavaME application, so
Can anyone recommend software or a .NET library that will check for bounced emails

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.