晚上看了电视没事做 YY了一个问题。苦思不得其解希望各路神仙给个提示。
很久以前.有一个部门Microsoft.其下有2个子部门.....如下面所表达的.
           Microsoft
              |
       BFSI        MFG
         |          |
        GM          IS
         |          | 
      PES SAP  EAS PES Testing public partial class _Default : System.Web.UI.Page
    {        //1000条数据 包括ID 姓名 部门名称
        //现在要插入数据库  检查如果数据库中有此记录 那么进行update 如果没有记录insert
        //无论是update 还是insert 都要判断这个部门在上面的树结构中是否存在          //问题:
        //判断1 当用户的部门名称在数据库中存在的时候 直接判断
        //判断2 当用户的部门为Microsoft BFSI 那么就要截取BFSI。来判断 那么如何判断要截取呢?
        //判断3 当用户的部门为BFS  那如何去判断BFS是属于BFSI呢?        //效率:
        //针对判断1: 上面直接判断的时候我打算用哈希表匹配 不知效率如何 是否有更快的
        //针对判断2: 没想出来
        //针对判断3: 没想出来
        //假设上面3个问题都解决了 
        //在nhibernate里 更新Merge的时候 是用Nhibernate的Merge好呢 
        //还是用拼SQL好呢?(ORACLE) 貌似ORACLE 在对批量操作这方面做的不是很好。        //目的 想求一个高效的方法来完成这一个操作 从判断部门 批量Merge到数据库        //代码如下:
        public static List<string> DepartMentList = new List<string>();
        protected void Page_Load(object sender, EventArgs e)
        {            DepartMentList.Add("Microsoft");
            DepartMentList.Add("Microsoft BFSI");
            DepartMentList.Add("BFSI");
            DepartMentList.Add("IS");
            DepartMentList.Add("MFG");
            DepartMentList.Add("Microsoft GM");
            DepartMentList.Add("MFG");
            DepartMentList.Add("Microsoft Testing");
            DepartMentList.Add("PE");
            DataTable Table_Info = new DataTable();
            DataColumn dc = null;
            dc = Table_Info.Columns.Add("ID", Type.GetType("System.Int32"));
            dc.AutoIncrement = true;
            dc.AutoIncrementSeed = 1;
            dc.AutoIncrementStep = 1;
            dc.AllowDBNull = false;
            dc = Table_Info.Columns.Add("EnglishName", Type.GetType("System.String"));
            dc = Table_Info.Columns.Add("ChineseName", Type.GetType("System.String"));
            dc = Table_Info.Columns.Add("Department", Type.GetType("System.String"));            for (int i = 0; i < 1000; i++)
            {
                DataRow dr = Table_Info.NewRow();
                dr[1] = RndStr(5, RndType.Char);
                dr[2] = RndStr(3, RndType.Str);
                dr[3] = EndDepartMent();
            }        }        public enum RndType
        {
            Char, Number, Both, Str
        };
        public static string RndStr(int Len, RndType type)
        {
            string s = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,W,X,Y,Z,啊,的,快,乐,安,徽,省,好,上,看,的,大,佬,万,科,阿,萨,德";
            string[] Chars = s.Split(',');
            Random Rnd = new Random();
            int Start = 0, End = 0;
            switch (type)
            {
                case RndType.Char:
                    Start = 0;
                    End = 26;
                    break;
                case RndType.Str:
                    Start = 26;
                    End = 44;
                    break;
            }
            s = " ";
            for (int i = 0; i < Len; i++)
            {
                s += Chars[Rnd.Next(Start, End)];
                System.Threading.Thread.Sleep(5);
            }
            return s;
        }
        public static string EndDepartMent()
        {
            Random Rnd = new Random();
            return DepartMentList[Rnd.Next(1, DepartMentList.Count)];
        }
    }

解决方案 »

  1.   

       Microsoft
          |
     BFSI    MFG
      |       |
      GM      IS
      |       | 
    PES SAP EAS PES Testing  错位了红的一组
      

  2.   

    好吧 我在阐述一下现在数据库中A表中 有个字段A 里面有 条数据为BFSI页面有个string 为 BFS我要把这个BFS插入到数据库  但是有外键限制 必须转换为A表中有的数据即BFSI  如何处理
    现在数据库中A表中 有个字段A 里面有 条数据为BFSI页面有个string 为 Microsoft BFSI我要把这个BFS插入到数据库  但是有外键限制(不能将) 必须转换为A表中有的数据即BFSI   如何处理
      

  3.   


    --测试数据
    declare @department table (departmentid int,departmentName varchar(9),pid int)
    insert into @department
    select 1,'Microsoft',0 union all
    select 2,'BFSI',1 union all
    select 3,'MFG',1 union all
    select 4,'GM',2 union all
    select 5,'IS',3 union all
    select 6,'PES',4 union all
    select 7,'SAP',4 union all
    select 8,'EAS',3 union all
    select 9,'PES',3 union all
    select 10,'Testing',3--得到某节点下的所有部门
    declare @i int
    set @i =0 --参数假定为1
    ;with maco as(
        select * from @department
        where pid = 0
        union all
        select a.*
        from @department a, maco b
        where a.pid = b.departmentid
    )
    select * from maco
    --查看结果
    /*
    departmentid departmentName pid
    ------------ -------------- -----------
    1            Microsoft      0
    2            BFSI           1
    3            MFG            1
    5            IS             3
    8            EAS            3
    9            PES            3
    10           Testing        3
    4            GM             2
    6            PES            4
    7            SAP            4
    */
      

  4.   

    哈哈 SQL犀利啊。我不是要实现树形- -!
      

  5.   

    --现在数据库中A表中,有个字段A,里面有数据为BFSI
    declare @A table (a varchar(4))
    insert into @A
    select 'BFSI'--页面有个string为BFS
    declare @bfs varchar(20)
    set @bfs='BFS'--我要把这个BFS插入到数据库,但是有外键限制,必须转换为A表中有的数据即BFSI
    insert into @A(a)
    select top 1 a from @A where charindex('BFS',a)>0--查看结果
    select * from @A
    /*
    a
    ----
    BFSI
    BFSI
    */
      

  6.   


    --现在数据库中A表中,有个字段A,里面有数据为BFSI
    declare @A table (a varchar(4))
    insert into @A
    select 'BFSI'--页面有个string为BFS
    declare @bfs varchar(20)
    set @bfs='BFS'--我要把这个BFS插入到数据库,但是有外键限制,必须转换为A表中有的数据即BFSI
    insert into @A(a)
    select top 1 a from @A where charindex('BFS',a)>0--页面有个string 为 Microsoft BFSI
    declare @p2 varchar(20)
    set @p2='Microsoft BFSI'
    insert into @A(a)
    select top 1 a from @A 
    where charindex('BFS',a)>0 or charindex(a,@p2)>0select * from @A
    /*
    a
    ----
    BFSI
    BFSI
    BFSI
    */
      

  7.   


    嗯 这个办法不错BFS是是B呢。 部门下一个BFSI 一个是BFMN  就不好办了。
      

  8.   

    我想出了一个办法。其实是脑筋死了。。导入的时候判断 是否跟外键表中的数据相符。。如果不相符的话 就抛个异常。。然后返回一个出错的记录 提示出来
    从新修改数据 一直判断到外键表中存在为止这样做更保险一些。。呵呵 叶子这种方法也不错 给300分。。
    继续下一个问题   批量Merge的问题
      

  9.   


    部门要有部门id的,仅凭字符串判断不了父子关系。如果字符串可以判断父子关系就需要tree编号:例如部门A:001 B:002 C:001001 D:002002这样就可以判断父子关系了。BFS Microsoft BFSI这样规则不固定,就不好判断了。
      

  10.   

    Department是一个词。M不要大写啦叶子的头像换的让我没法转移过来子夜的问题中
            //判断1 当用户的部门名称在数据库中存在的时候 直接判断
            //判断2 当用户的部门为Microsoft BFSI 那么就要截取BFSI。来判断 那么如何判断要截取呢?
            //判断3 当用户的部门为BFS  那如何去判断BFS是属于BFSI呢?第一个和第二个可以接受,第三个我就不大好接收了。那如果有这样的部门MSI MSII 那你要是输入为MS怎么办对吧。关于判断二现实中我经常遇到,比如IS,Internet Service,IS部门====。
    我的办法很不高效
    1、如果部门的关联不大,比如没有两个很相似的部门,那么就直接检查匹配度
    2、如果部门的关联大,那就没办法了,做个汇总,比如['IS','Internet Service'...],KEY呢就是数据库的IS。打完酱油了,飘过
      

  11.   

    外面的数据是:1000条数据 包括ID 姓名 部门名称
    应该部门员工的记录但是里面是部门表呀?怎么更新?
    declare @table table (ID int,姓名 varchar(4),部门名称 varchar(9),c4 varchar(4))
    insert into @table
    select 1,'张三','Microsoft','BFSI' union all
    select 2,'李四','BFSI',null union all
    select 3,'王五','Microsoft',null union all
    select 4,'刘六','BFSI',null
    --...
    select * from @table
    /*
    ID          姓名   部门名称      c4
    ----------- ---- --------- ----
    1           张三   Microsoft BFSI
    2           李四   BFSI      NULL
    3           王五   Microsoft NULL
    4           刘六   BFSI      NULL
    */
    有部门员工关系表吗?
      

  12.   


    --假设数据库中有三个部门
    declare @department table (departmentid int,departmentName varchar(9))
    insert into @department
    select 1,'Microsoft' union all
    select 2,'BFSI' union all
    select 3,'MFG'
    select * from @department--假设现在每个部门只有1个人
    declare @staff table(userid int identity,username varchar(10),departmentid int)
    insert into @staff
    select '张三',1 union all
    select '李四',2 union all
    select '王五',3
    select * from @staff--假设外面又来了100人(暂时只模拟4条)declare @table table (ID int,姓名 varchar(2),部门名称 varchar(15))
    insert into @table
    select 1,'a1','Microsoft1' union all
    select 2,'a2','BFSIAS' union all
    select 3,'a3','Microsoft2' union all
    select 4,'a4','BFSICF'select * from @table
    /*
    要把这100个人批量插入员工表中,然后部门根据名称匹配,是这个意思吗?如果进来的人员的部门是ABC,匹配不到,
    则该人员不插入,还是插入后,自动创建部门到部门表?
    */
      

  13.   

    在判断的时候,如果是case when 还是单独走触发器我觉得效果都不好
    建议分开处理:如下--假设数据库中有三个部门
    declare @department table (departmentid int,departmentName varchar(9))
    insert into @department
    select 1,'Microsoft' union all
    select 2,'BFSI' union all
    select 3,'MFG'
    --select * from @department--假设现在每个部门只有1个人
    declare @staff table(userid int identity,username varchar(10),departmentid int)
    insert into @staff
    select '张三',1 union all
    select '李四',2 union all
    select '王五',3
    --select * from @staff--假设外面又来了100人(暂时只模拟4条)declare @table table (ID int,姓名 varchar(2),部门名称 varchar(15))
    insert into @table
    select 1,'a1','Microsoft1' union all
    select 2,'a2','BFSIAS' union all
    select 3,'a3','Microsoft2' union all
    select 4,'a4','ABC'--select * from @tableinsert into @staff
    select * from 
    (
    select 姓名,(select top 1 departmentid from @department 
    where charindex(departmentName,部门名称)>0) as did from @table
    ) aa
    where did is not null  --这是只匹配上的  --把where 条件改为 where did is null 就是进来的部门不存在的--相当于把进来的1000条数据直接分为2个部分了,这样处理起来方便一些,不知道我理解的对不对。select * from @staff--插入后的结果:
    /*
    userid      username   departmentid
    ----------- ---------- ------------
    1           张三         1
    2           李四         2
    3           王五         3
    4           a1         1
    5           a2         2
    6           a3         1
    */
      

  14.   


    也是匹配charindex啊我感觉还是我想多了。。呵呵 万一用户数据是B的话或者M的话就不好匹配了保险做法 还是抛异常吧。叶子对ORACLE 批量操作有想法没?
      

  15.   


    笔误。。第三点 也是这么想的。还是抛异常 返回 错误行信息 这样比较好。不知前辈对ORACLE批量操作有经验没
      

  16.   

    假设数据库里有两个部门是B1,B2
    外面传进来的是B,如何对应?打算怎么抛出异常?提示部门无法正确匹配?
      

  17.   

    如果数据是一条一条进来的:
    当部门不存在的时候,提示:导入人员所在部门不存在,是否创建该部门,并继续导入。
    当部门全部匹配的时候不提示,直接导入。
    当部门出现上述情况的时候,两个部门是B1,B2,用户导入的参数是B,提示数据库中没有这个部门,是否导入相关部门B1或是B2中,请选择 。
      

  18.   

    对。就是怕这种情况 或者定一个 匹配3个字符以上 或者部门字数的50%以上就替换 也可以的。。如果小于50% 那么就抛异常。下来就是效率了。其实以前做过类似 感觉ORACLE 有个专门做批量处理要比Nhibernate一条一条的快但是每一条都要遍历 就很影响效率的。
      

  19.   

    这些都是我YY出来的。。呵呵 假如就是个TXT有就UPDATE 没有就INSERT 这个表中还有其他多余的字段 所以考虑下效率看看  你还不睡啊。我打算去写写。
      

  20.   


    --数据库中的表
    declare @table table (id int identity,colone varchar(2),coltow int)
    insert into @table
    select 'A',5 union all
    select 'B',6 union all
    select 'C',7 union all
    select 'D',9
    --select * from @table--外来数据
    declare @t table (a varchar(2),b int)
    insert into @t
    select 'B2',11 union all
    select 'C1',12 union all
    select 'C2',14 union all
    select 'D',3--插入数据
    insert into @table(colone,coltow)
    select * from @t--更新可以自己定义规则
    update @table set colone=substring(colone,1,1)select * from @table
    /*
    id          colone coltow
    ----------- ------ -----------
    1           A      5
    2           B      6
    3           C      7
    4           D      9
    5           B      11
    6           C      12
    7           C      14
    8           D      3
    */
      

  21.   

    那就不需要Nhi了。直接在oralce里进行处理。
      

  22.   

    无论是sql server 还是oracle 都是关系型数据库,相当于处理两个表了呗。
    我只是提个思路。