CLR:多参数总结,参数不是在最终输出? [英] CLR: Multi Param Aggregate, Argument not in Final Output?

查看:143
本文介绍了CLR:多参数总结,参数不是在最终输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我的分隔符没有出现在最终的输出?它的初始化是一个逗号,但我只得到各属性之间〜5空格使用:

  SELECT [的article_id]
         ,dbo.GROUP_CONCAT(0,t.tag_name,,)AS山口
    FROM [AdventureWorks的]。[DBO]。[ARTICLE_TAG_XREF] ATX
    JOIN [AdventureWorks的]。[DBO]。[标签]的t ON t.tag_id = atx.tag_id
GROUP BY的article_id
 

该位DISTINCT的作品很好,但它的厚积薄发范围内进行操作......

输出:

 的article_id |关口
-------------------------------------------------
1 |一个A B C
 

更新:值之间的过量空间是因为所限定为NCHAR(10)的列中,所以10个字符将出现在输出中。在我的部分愚蠢的错误...

解决方案


随着马丁·史密斯的关于与工作的帮助写(的BinaryWriter W)方法,此更新为我的作品:

 公共无效写入(的BinaryWriter W)
{
    w.Write(list.Count);
    的for(int i = 0; I< list.Count;我++)
    {
        如果(ⅰ&所述; list.Count  -  1)
        {
            w.Write(名单[I]的ToString()+分隔符);
        }
        其他
        {
            w.Write(名单[I]的ToString());
        }
    }
}
 

的问题:


为什么上面的解决我的问题?为什么不会它让我使用一个以上的 w.write 调用中FOR循环?

C#code:


 使用系统;
使用System.Data这;
使用System.Data.SqlClient的;
使用System.Data.SqlTypes;
使用Microsoft.SqlServer.Server;
使用的System.Xml.Serialization;
使用的System.Xml;
使用System.IO;
System.Collections中使用;
使用System.Text;

[可序列化]
[SqlUserDefinedAggregate(Format.UserDefined,MaxByteSize = 8000)
公共结构GROUP_CONCAT:IBinarySerialize
{
    ArrayList的名单;
    字符串分隔符;

    公共无效的init()
    {
        名单=新的ArrayList();
        定界符=,;
    }

    公共无效累加(SqlBoolean isDistinct,的SqlString价值的SqlString分隔符)
    {
        分隔符=(separator.IsNull)? ,:separator.Value;

        如果(!Value.IsNull)
        {
            如果(isDistinct)
            {
                如果(!list.Contains(Value.Value))
                {
                    list.Add(Value.Value);
                }
            }
            其他
            {
                list.Add(Value.Value);
            }
        }
    }

    公共无效合并(GROUP_CONCAT集团)
    {
        list.AddRange(Group.list);
    }

    公众的SqlString终止()
    {
        字符串[]字符串=新的字符串[list.Count]

        的for(int i = 0; I< list.Count;我++)
        {
            字符串[我] =列表[我]的ToString();
        }

        返回新的SqlString(的string.join(分隔符,字符串));
    }

    #地区IBinarySerialize会员

    公共无效读(BinaryReader在R)
    {
        INT ItemCount中= r.ReadInt32();
        名单=新的ArrayList(ItemCount中);

        的for(int i = 0; I< ItemCount中,我++)
        {
            this.list.Add(r.ReadString());
        }
    }

    公共无效写入(的BinaryWriter W)
    {
        w.Write(list.Count);
        的foreach(字符串s在名单)
        {
            w.Write(多个);
        }
    }
    #endregion
}
 

解决方案

这里的问题是,你不序列化分隔符。地址:

  w.Write(分隔符)
 

在你写方法中的第一行和

 分隔符= r.ReadString();
 

在你阅读方法的第一道防线。

关于您的问题,提出解决方法:

  

为什么上面的解决我的问题?

它没有。它仅仅是曾与你的测试方案。

  

为什么那岂不是让我使用一个以上的w.write调用中FOR循环?

Write方法需要与阅读方法兼容。如果你写两个字符串和只读之一,那么它是行不通的。这里的想法是,你的对象可以被从存储器中删除,然后加载。这是写入和读取所应该做的。在你的情况 - 这的确是发生了,你是不是能够保持目标值

Why is my delimiter not appearing in the final output? It's initialized to be a comma, but I only get ~5 white spaces between each attribute using:

  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

The bit for DISTINCT works fine, but it operates within the Accumulate scope...

Output:

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

Update: The excess space between values is because the column as defined as NCHAR(10), so 10 characters would appear in the output. Silly mistake on my part...

Solution


With Martin Smith's help about working with the Write(BinaryWriter w) method, this update works for me:

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());
        }
    }
}

The Question:


Why does the above solve my problem? And why wouldn't it let me use more than one w.write call inside the FOR loop?

C# Code:


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
}

解决方案

The problem here is that you do not serialize delimiter. Add:

w.Write(delimiter)

as a first line in your Write method and

delimiter = r.ReadString();

as a first line in your Read method.

Regarding your questions to suggested work-around:

Why does the above solve my problem?

It does not. It merely worked with your test scenario.

And why wouldn't it let me use more than one w.write call inside the FOR loop?

Write method needs to be compatible with Read method. If you write two strings and read only one then it is not going to work. The idea here is that your object may be removed from the memory and then loaded. This is what Write and Read are supposed to do. In your case - this indeed was happening and you were not able to keep the object value.

这篇关于CLR:多参数总结,参数不是在最终输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆