Pregunta

Leí aquí (y en otros lugares) que es posible, en SQL Server 2008, crear un agregado definido por el usuario que pueda devolver una cadena de más de 8000 caracteres. Esto es exactamente lo que necesito.

Supuestamente, el método es establecer maxByteSize en -1 en lugar de un número entre 1 y 8000; esto debería permitir cualquier tamaño de hasta 2 GB.

Por alguna razón, aparentemente, no puede implementar directamente desde Visual Studio 2008 si usa esta configuración; por lo que necesita implementar manualmente.

Entonces: construyo mi proyecto - GroupConcat (que se supone que simula el agregador group_concat de MySQL) - que me da, en la carpeta bin del proyecto, un archivo "SqlClassLibrary.dll". Siguiendo las instrucciones de la página vinculada anteriormente, compilo el ensamblaje en SQL Server. El comando se ejecuta con éxito. Sin embargo, cuando intento realmente usar el agregador groupconcat:

seleccione el departamento, dbo.groupconcat (projectNumber) del grupo de proyectos por departamento

... dice que no se puede encontrar. Todo esto funciona bien si configuro maxByteSize en 8000 y lo implemento directamente desde VS2008, pero necesito > 8000. ¿Alguien sabe lo que estoy haciendo mal?

Gracias -dan

NOTA: Necesito específicamente tener una función de agregador groupconcat en lugar de usar algunos de los trucos de SQL Server que he visto con frecuencia.

¿Fue útil?

Solución 2

Lo descubrí ... Después de compilar la solución en Vis Studio, asumiendo que dejé caer el archivo .dll que crea en c: \ temp y lo llamé GroupConcat.dll:

CREATE ASSEMBLY GroupConcat from 'C:\temp\GroupConcat.dll' with permission_set = safe
GO

CREATE AGGREGATE groupconcat(@input nvarchar(max))
RETURNS nvarchar(max)
EXTERNAL NAME GroupConcat
GO

Eso lo hace.

Otros consejos

Alternativamente, puede usar la propiedad MaxSize de SqlFacetAttribute para indicar el tamaño de varchar. Tenga en cuenta que en el siguiente ejemplo apliqué este atributo a los parámetros SqlString en el método Accumulate y al valor de retorno del método Terminate . Esto da como resultado la siguiente firma SQL:

AGREGATE [dbo]. [Concatenate] (@value nvarchar (max), @order int, @seperator nvarchar (max)) DEVOLUCIONES nvarchar (max)

[Serializable]
[SqlUserDefinedAggregate(
    Format.UserDefined,
    IsInvariantToOrder      = true,
    IsInvariantToNulls      = true,
    IsInvariantToDuplicates = false,
    IsNullIfEmpty           = false,
    MaxByteSize             = -1)]
public struct Concatenate : IBinarySerialize
{
    public void Init();

    public void Accumulate([SqlFacet(MaxSize = -1)] SqlString value,
                                                    SqlInt32  order,
                           [SqlFacet(MaxSize = -1)] SqlString seperator);

    public void Merge(Concatenate group);

    [return: SqlFacet(MaxSize = -1)]
    public SqlString Terminate();

    public void Read(BinaryReader r);

    public void Write(BinaryWriter w);
}

No sé si esto es más " correcto " de lo que terminaste haciendo, pero parece más natural.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top