Domanda

Ho letto qui (e altrove) che è possibile, in SQL Server 2008, creare un aggregato definito dall'utente che può restituire una stringa più lunga di 8000 caratteri. Questo è esattamente ciò di cui ho bisogno.

Presumibilmente, il metodo consiste nell'impostare maxByteSize su -1 anziché un numero tra 1 e 8000; questo dovrebbe consentire qualsiasi dimensione fino a 2 GB.

Per qualche motivo, a quanto pare, non è possibile distribuire direttamente da Visual Studio 2008 se si utilizza questa impostazione; quindi è necessario distribuire manualmente.

Quindi: costruisco il mio progetto - GroupConcat (che dovrebbe simulare l'aggregatore group_concat di MySQL) - che mi dà, nella cartella bin del progetto, un file " SqlClassLibrary.dll " ;. Per le istruzioni sulla pagina collegata sopra, ho creato l'assembly in SQL Server. Il comando viene eseguito correttamente. Tuttavia, quando provo a usare l'aggregatore groupconcat:

seleziona reparto, dbo.groupconcat (projectNumber) dal projectlead raggruppa per dipartimento

... dice che non può essere trovato. Funziona tutto bene se imposto maxByteSize su 8000 e lo distribuisco direttamente da VS2008, ma ho bisogno di > 8000. Qualcuno sa cosa sto facendo di sbagliato?

Grazie -Dan

NOTA: in particolare ho bisogno di avere una funzione di aggregazione groupconcat piuttosto che usare alcuni dei trucchi di SQL Server che ho visto spesso.

È stato utile?

Soluzione 2

Capito ... Dopo aver creato la soluzione in Vis Studio, supponendo che abbia lasciato cadere il file .dll che crea in c: \ temp e l'ho chiamato 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

Lo fa.

Altri suggerimenti

In alternativa, puoi usare la proprietà MaxSize di SqlFacetAttribute per indicare la dimensione del varchar. Si noti che nell'esempio seguente ho applicato questo attributo ai parametri SqlString nel metodo Accumulate e al valore restituito del metodo Terminate . Ciò comporta la seguente firma SQL:

AGGREGATE [dbo]. [Concatenate] (@value nvarchar (max), @order int, @seperator nvarchar (max)) RITORNI 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);
}

Non so se questo è più " corretto " rispetto a quello che hai finito per fare, ma sembra più naturale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top