CLR: Много Агрегат Param, Аргумент не в Окончательном результате?

Почему мой разделитель не появляется в окончательном результате? Это инициализируется, чтобы быть запятой, но я только получаю ~5 пробелов между каждым использованием атрибута:

  SELECT [article_id]
         , dbo.GROUP_CONCAT(0, t.tag_name, ',') AS col
    FROM [AdventureWorks].[dbo].[ARTICLE_TAG_XREF] atx
    JOIN [AdventureWorks].[dbo].[TAGS] t ON t.tag_id = atx.tag_id
GROUP BY article_id

Бит для ОТЛИЧНОГО хорошо работает, но он работает в Накапливать объеме...

Вывод:

article_id  |  col
-------------------------------------------------
1           |  a         a         b         c         

Обновление: избыточное пространство между значениями - то, потому что столбец столь же определил как NCHAR (10), таким образом, 10 символов появились бы в выводе. Глупая ошибка с моей стороны...

Решение


Со справкой Martin Smith о работе с Write(BinaryWriter w) метод, это обновление работает на меня:

public void Write(BinaryWriter w)
{
    w.Write(list.Count);
    for (int i = 0; i < list.Count; i++ )
    {
        if (i < list.Count - 1)
        {
            w.Write(list[i].ToString() + delimiter);
        }
        else 
        {
            w.Write(list[i].ToString());
        }
    }
}

Вопрос:


Почему вышеупомянутое решает мою проблему? И почему это не позволило бы мне использовать больше чем один w.write призвать в К циклу?

Код C#:


using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Collections;
using System.Text;

[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize = 8000)]
public struct GROUP_CONCAT : IBinarySerialize
{
    ArrayList list;
    string delimiter;

    public void Init()
    {
        list = new ArrayList();
        delimiter = ",";
    }

    public void Accumulate(SqlBoolean isDistinct, SqlString Value, SqlString separator)
    {
        delimiter = (separator.IsNull) ? "," : separator.Value ;

        if (!Value.IsNull)
        {
            if (isDistinct)
            {
                if (!list.Contains(Value.Value))
                {
                    list.Add(Value.Value);
                }
            }
            else
            {
                list.Add(Value.Value);
            }            
        }
    }

    public void Merge(GROUP_CONCAT Group)
    {
        list.AddRange(Group.list);
    }

    public SqlString Terminate()
    {
        string[] strings = new string[list.Count];

        for (int i = 0; i < list.Count; i++)
        {
            strings[i] = list[i].ToString();
        }

        return new SqlString(string.Join(delimiter, strings));
    }

    #region IBinarySerialize Members

    public void Read(BinaryReader r)
    {
        int itemCount = r.ReadInt32();
        list = new ArrayList(itemCount);

        for (int i = 0; i < itemCount; i++)
        {
            this.list.Add(r.ReadString());
        }
    }

    public void Write(BinaryWriter w)
    {
        w.Write(list.Count);
        foreach (string s in list)
        {
            w.Write(s);
        }
    }
    #endregion
}
5
задан OMG Ponies 30 May 2010 в 22:39
поделиться

1 ответ

Проблема в том, что вы не сериализуете разделитель. Добавьте:

w.Write(delimiter)

в качестве первой строки в методе записи и

delimiter = r.ReadString();

в качестве первой строки в методе чтения.

Относительно ваших вопросов к предлагаемому обходному пути:

Почему это решает мою проблему?

Нет. Он просто работал с вашим тестовым сценарием.

И почему бы мне не использовать более одного вызова w.write внутри цикла FOR?

Метод записи должен быть совместим с методом чтения. Если вы напишете две строки и прочитаете только одну, это не сработает. Идея здесь в том, что ваш объект может быть удален из памяти, а затем загружен. Это то, что должны делать Write и Read. В вашем случае - это действительно происходило, и вы не смогли сохранить значение объекта.

5
ответ дан 14 December 2019 в 19:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: