zoukankan      html  css  js  c++  java
  • PCB MS CLR 聚合函数 joinString加排序实现

    准备着手,动态列SQL查询,要实现动态列SQL,会运用到聚合函数,而SQL本身聚合函数有限,

    无满足此用户任意字段组合变化,再加上工艺流程重复相同工序,如;沉铜1,沉铜2对应工序代码都是相同的

    而通常聚合以后,数据排列顺序失效,如果要实现,需采用低效的方式实现。

    以其中一个:聚合函数joinString 为例说明,它是如何实现高效的

    原来SQL实现:采用:FOR XML PATH ,比较低效,为了让效率高一点,需建立临时表,这样效率才稍好些,但这样实现比较呆呆的。

    SELECT pdctno,techname,GlobalOrder INTO #ppeflow1
      FROM [FP_EMS_DB].[dbo].[V_PPEFlow]
    WHERE pdctno IN (SELECT pdctno FROM #EDS_StateCam) AND  FlowLevel = 2
    
    SELECT aa.pdctno
    ,(SELECT '' + bb.techname   + '--'  FROM #ppeflow1 bb where bb.pdctno = aa.pdctno ORDER BY  bb.globalOrder FOR XML PATH('')) flowString
      FROM #ppeflow1 aa
    GROUP BY pdctno 

    更改后SQL实现:这样一看简洁多了。

    SELECT pdctno,FP_EMSDB_PUB.dbo.JoinString(techname,'--',GlobalOrder) flowString
      FROM [FP_EMS_DB].[dbo].[V_PPEFlow]
    WHERE pdctno IN (
        SELECT pdctno FROM #EDS_StateCam
    ) AND  FlowLevel = 2
    GROUP BY pdctno 

    SQL实现效果

    net实现代码:

     [Serializable]
        [Microsoft.SqlServer.Server.SqlUserDefinedAggregate(
          Format.UserDefined,
          IsInvariantToDuplicates = false,
          IsInvariantToNulls = true,
          IsInvariantToOrder = false,
          MaxByteSize = 8000,
          Name = "JoinString")]
        public struct UserJoinString : IBinarySerialize
        {
            private IList<stringOrder> ValueList;
            private string JoinString_;
            private string  Separate_;
            /// <summary>
            /// 查询处理器使用此方法初始化聚合的计算
            /// </summary>
            public void Init()
            {
                ValueList = new List<stringOrder>();
                Separate_ = "";
                JoinString_ = "";
            }
            /// <summary>
            /// 查询处理器使用此方法累计聚合值
            /// </summary>
            /// <param name="Value"></param>
            public void Accumulate(SqlString Value, SqlString Separate,SqlInt32 Orderno) //1
            {
                if (Separate_.Length == 0)
                    Separate_ = Separate.ToString();
                ValueList.Add(new SQLClr.stringOrder() {  orderno = (int)Orderno , itemstring =Value.ToString() });
            }
    
            /// <summary>
            /// 查询处理器使用此方法合并聚合的多个部分计算的值
            /// </summary>
            /// <param name="Group"></param>
            public void Merge(UserJoinString Group) //无效  暂不用
            {
                //JoinString_.Append(Group.JoinString_ ); 
            }
    
            /// <summary>
            /// 此方法用于返回完成聚合计算的结果
            /// </summary>
            /// <returns></returns>
            public SqlString Terminate()
            {
                return new SqlString(JoinString_); //4
            }
    
            /// <summary>
            ////// </summary>
            /// <param name="r"></param>
            public void Read(System.IO.BinaryReader r) //3
            {
                JoinString_ = r.ReadString();
                Separate_ =r.ReadString();
            }
    
            /// <summary>
            ////// </summary>
            /// <param name="w"></param>
            public void Write(System.IO.BinaryWriter w)  //2
            {
                w.Write(string.Join(Separate_, ValueList.OrderBy(tt => tt.orderno).Select(tt => tt.itemstring).ToArray()));
                w.Write(Separate_);
           
            }
        }
    
        [Serializable]
        public class stringOrder
        {
            public string itemstring { get; set; }
            public int orderno { get; set; }
        }

    聚合函数创建SQL:

    --第一步:先删函数
    --第二步:再更新DLL
    --第三步:再创建函数
    IF EXISTS(SELECT* FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[JoinString]') AND type = N'AF') 
    DROP AGGREGATE[dbo].[JoinString]
    
    ALTER  ASSEMBLY SQLfunctionAssembly
    FROM 'D:SQLClr.dll'      --改为自己C#写的dll路径填写
    WITH PERMISSION_SET = UNSAFE;   
    
    
    CREATE AGGREGATE[dbo].[JoinString]
    (@Value[nvarchar](4000),      --聚合字符串
    @Separate[nvarchar](20),      --分隔符
    @Orderno    BIT               --排序号
    )
    RETURNS[nvarchar](4000)
    EXTERNAL NAME[SQLfunctionAssembly].[SQLClr.UserJoinString]
  • 相关阅读:
    单例模式中的懒汉式以及线程安全性问题
    单例模式中的饿汉模式
    自我管理的8个好习惯
    从java字节码角度看线程安全性问题
    工作上的建议
    从线程的优先级看饥饿问题
    多线程存在哪些风险
    DirectX SDK (June 2010)安装错误S1023,解决方法
    Microsoft DirectX SDK 2010 版本下载
    如果程序集是从 Web 上下载的,即使它存储于本地计算机,Windows 也会将其标记为 Web 文件,http://go.microsoft.com/fwlink/?LinkId=179545
  • 原文地址:https://www.cnblogs.com/pcbren/p/9343602.html
Copyright © 2011-2022 走看看