不能在 PIVOT 运算符中使用,因为它对于 NULL 不是不变的
我在 SQL Server 2008 中为字符串列创建一个聚合函数。C
# 代码如下所示:
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.IO;
using Microsoft.SqlServer.Server;
[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize = 8000)]
public struct strconcat : IBinarySerialize
{
private List<String> values;
public void Init()
{
this.values = new List<String>();
}
public void Accumulate(SqlString value = new SqlString())
{
this.values.Add(value.Value);
}
public void Merge(strconcat value)
{
this.values.AddRange(value.values.ToArray());
}
public SqlString Terminate()
{
return new SqlString(string.Join(", ", this.values.ToArray()));
}
public void Read(BinaryReader r)
{
int itemCount = r.ReadInt32();
this.values = new List<String>(itemCount);
for (int i = 0; i <= itemCount - 1; i++)
{
this.values.Add(r.ReadString());
}
}
public void Write(BinaryWriter w)
{
w.Write(this.values.Count);
foreach (string s in this.values)
{
w.Write(s);
}
}
}
在 SQL 中查询:
DECLARE @listCol NVARCHAR(2000)
SELECT @listCol = STUFF(( SELECT '],[' + A.Name
FROM Attribute A,Category C
WHERE A.CategoryId = C.Id
ORDER BY A.DisplayOrder DESC
FOR XML PATH('')), 1, 2, '') + ']'
DECLARE @query NVARCHAR(2000)
SET @query =
N'SELECT * FROM (SELECT P.*,A.Name AttributeName,PA.OriginalValue FROM Product P,Product_Attribute PA, Attribute A WHERE P.Id = PA.ProductId AND A.Id = PA.AttributeId) src
PIVOT
(
dbo.strconcat(OriginalValue) FOR AttributeName
IN ('+@listCol+')) AS pvt'
EXECUTE (@query)
但 SQL Server 返回错误:
消息 406,第 16 级,状态 1,第 5 行
dbo.strconcat 不能在 PIVOT 运算符中使用,因为它对于 NULL 不是不变的。
我用谷歌搜索但不知道如何修复它。
请帮我!
I create an aggregate function for string column in SQL Server 2008.
C# code look like this:
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.IO;
using Microsoft.SqlServer.Server;
[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize = 8000)]
public struct strconcat : IBinarySerialize
{
private List<String> values;
public void Init()
{
this.values = new List<String>();
}
public void Accumulate(SqlString value = new SqlString())
{
this.values.Add(value.Value);
}
public void Merge(strconcat value)
{
this.values.AddRange(value.values.ToArray());
}
public SqlString Terminate()
{
return new SqlString(string.Join(", ", this.values.ToArray()));
}
public void Read(BinaryReader r)
{
int itemCount = r.ReadInt32();
this.values = new List<String>(itemCount);
for (int i = 0; i <= itemCount - 1; i++)
{
this.values.Add(r.ReadString());
}
}
public void Write(BinaryWriter w)
{
w.Write(this.values.Count);
foreach (string s in this.values)
{
w.Write(s);
}
}
}
And query in SQL:
DECLARE @listCol NVARCHAR(2000)
SELECT @listCol = STUFF(( SELECT '],[' + A.Name
FROM Attribute A,Category C
WHERE A.CategoryId = C.Id
ORDER BY A.DisplayOrder DESC
FOR XML PATH('')), 1, 2, '') + ']'
DECLARE @query NVARCHAR(2000)
SET @query =
N'SELECT * FROM (SELECT P.*,A.Name AttributeName,PA.OriginalValue FROM Product P,Product_Attribute PA, Attribute A WHERE P.Id = PA.ProductId AND A.Id = PA.AttributeId) src
PIVOT
(
dbo.strconcat(OriginalValue) FOR AttributeName
IN ('+@listCol+')) AS pvt'
EXECUTE (@query)
But SQL Server returns an error:
Msg 406, Level 16, State 1, Line 5
dbo.strconcat cannot be used in the PIVOT operator because it is not invariant to NULLs.
I googled it but don't know how to fix it.
Please help me!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您的聚合对于空值不变,则需要在 SqlUserDefinedAggregateAttribute,类似于:
IsInvariantToNulls 属性将要求描述为:
看看您的聚合,我认为您可能需要在
Add
方法中做一些工作 - 如果传入的值为 null,也许不将其添加到列表中?If your aggregate is invariant to nulls, you need to mark it as such in the SqlUserDefinedAggregateAttribute, something like:
The IsInvariantToNulls property describes the requirement as:
Looking at your aggregate, I think you might need to do some work in your
Add
method - if the passed in value is null, maybe don't add it to the list?