sql server 2008 - T-SQL CLR: Can you CREATE AGGREGATE with optional parameter(s)? -
i'm hoping able allow optional parameters specified, can overload accumulate() method, can done?
i'd overload allow delimiter specified, i've seen others must force delimiter specified behaviour doesn't suit.
create aggregate dbo.concatenate (@input nvarchar(max), <optional parameter here>) returns nvarchar(max) for reference, here aggregate class code contains accumulate() method i'm looking overload:
using system; using system.data; using microsoft.sqlserver.server; using system.data.sqltypes; using system.io; using system.text; namespace clr.utilities { /// <summary> /// <list type="references"> /// <reference> /// <name>how to: create , run clr sql server aggregate</name> /// <link>http://msdn.microsoft.com/en-us/library/91e6taax(v=vs.90).aspx</link> /// </reference> /// <reference> /// <name>sqluserdefinedaggregateattribute</name> /// <link>http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.server.sqluserdefinedaggregateattribute(v=vs.90).aspx</link> /// </reference> /// <reference> /// <name>invoking clr user-defined aggregate functions (provides seed code function)</name> /// <link>http://technet.microsoft.com/en-us/library/ms131056.aspx</link> /// </reference> /// </list> /// </summary> [serializable] [sqluserdefinedaggregate( format.userdefined, //use clr serialization serialize intermediate result isinvarianttonulls = true, //optimizer property isinvarianttoduplicates = false, //optimizer property isinvarianttoorder = false, //optimizer property maxbytesize = -1) //no maximum size in bytes of persisted value ] public class concatenate : ibinaryserialize { /// <summary> /// variable holds intermediate result of concatenation /// </summary> private stringbuilder intermediateresult; /// <summary> /// initialize internal data structures /// </summary> public void init() { this.intermediateresult = new stringbuilder(); } /// <summary> /// accumulate next value, not if value null /// </summary> /// <param name="value"></param> public void accumulate([sqlfacet(maxsize = -1)] sqlstring value) { if (value.isnull) { return; } this.intermediateresult.append(value.value.trim()).append(','); } /// <summary> /// merge partially computed aggregate aggregate. /// </summary> /// <param name="other"></param> public void merge(concatenate other) { this.intermediateresult.append(other.intermediateresult); } /// <summary> /// called @ end of aggregation, return results of aggregation. /// </summary> /// <returns></returns> [return: sqlfacet(maxsize = -1)] public sqlstring terminate() { string output = string.empty; //delete trailing comma, if if (this.intermediateresult != null && this.intermediateresult.length > 0) { output = this.intermediateresult.tostring(0, this.intermediateresult.length - 1).trim(); } return new sqlstring(output); } public void read(binaryreader r) { intermediateresult = new stringbuilder(r.readstring()); } public void write(binarywriter w) { w.write(this.intermediateresult.tostring().trim()); } } } and here code deployment i'd modify if optional parameters can set:
if exists (select * sys.objects object_id = object_id(n'[dbo].[concatenate]') , type = n'af') drop aggregate [dbo].[concatenate] go if exists (select * sys.assemblies asms asms.name = n'clr.utilities' , is_user_defined = 1) drop assembly [clr.utilities] go alter database [databasename] set trustworthy on go create assembly [clr.utilities] 'c:\path\to\file\clr.utilities.dll' permission_set = unsafe go create aggregate [dbo].[concatenate] (@input nvarchar(max)) returns nvarchar(max) external name [clr.utilities].[clr.utilities.concatenate] go grant execute on [dbo].[concatenate] public go
as far know, there's no way make clr function or aggregate optional parameters , that's sad.
Comments
Post a Comment