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]
  • 相关阅读:
    怎么判断自己在不在一家好公司?
    超全!互联网大厂的薪资和职级一览
    Nginx 又一牛 X 功能!流量拷贝
    时间管理之四象限法则
    罗永浩一个坑位卖60万脏钱背后:放下面子赚钱,才是成年人最大的体面
    2020 年 4月全国程序员工资出炉
    一次 SQL 查询优化原理分析(900W+ 数据,从 17s 到 300ms)
    “Hey Siri” 背后的黑科技大揭秘!
    一文讲透高薪的本质!
    python UnicodeDecodeError: 'gbk' codec can't decode byte 0x99 in position 87: illegal multibyte sequence异常解决
  • 原文地址:https://www.cnblogs.com/pcbren/p/9343602.html
Copyright © 2011-2022 走看看