Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Изравняване на асоциативната таблица към колона с много стойности?

Създадох CLR агрегатна функция който приема varchar колона и връща всички нейни стойности, разделени със запетаи. С други думи, той обединява няколко низа в списък, разделен със запетаи. Сигурен съм, че неговата производителност е много по-добра от всеки T-Sql трик .

Като всяка агрегатна функция, тя може да се използва в комбинация с group by . Например:

SELECT id, name, desc, JoinStrings(CONVERT(VARCHAR(20), category_id))
FROM product p
INNER JOIN category_products c ON p.category_id = c.category_id
GROUP BY id, name, desc

Ето кода на C# за създаване на CLR модул в Sql Server 2008:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;


[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToDuplicates=false, IsInvariantToOrder=false, IsInvariantToNulls=true, MaxByteSize=-1)]
public struct JoinStrings : IBinarySerialize
{
    private char[] sb;
    private int pos;
    public void Init()
    {
        sb = new char[512000];
        pos = 0;
    }

    public void Accumulate(SqlString Value)
    {
        if (Value.IsNull) return;
        char[] src = Value.ToString().ToCharArray();
        Array.Copy(src, 0, sb, pos, src.Length);
        pos += src.Length;
        sb[pos] = ',';
        pos++;
    }

    public void Merge(JoinStrings Group)
    {
        Accumulate(Group.Terminate());
    }

    public SqlString Terminate()
    {
        if (pos <= 0) 
            return new SqlString();
        else
            return new SqlString(new String(sb, 0, pos-1));
    }

    public void Read(System.IO.BinaryReader r)
    {
        this.Init();
        pos = r.ReadInt32();
        r.Read(sb, 0, pos);
    }

    public void Write(System.IO.BinaryWriter w)
    {
        w.Write(pos);
        w.Write(sb, 0, pos);
    }
}

Ето кодът за създаване на функцията (въпреки че внедряването от Visual Studio трябва да го направи автоматично):

CREATE AGGREGATE [dbo].[JoinStrings]
(@s [nvarchar](4000))
RETURNS[nvarchar](max)
EXTERNAL NAME [YouAssemblyName].[JoinStrings]


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Превключване на дял в SQL Server (T-SQL)

  2. Динамичен SQL и оптимизация на съхранена процедура

  3. Не може да се получи информация за група/потребител на Windows NT

  4. Външният ключ създава ли автоматично индекс?

  5. Грешка при задействане:Текущата транзакция не може да бъде ангажирана и не може да поддържа операции, които записват в регистрационния файл