工作中遇到的问题和解决办法9

时间:2021-07-23 15:29:51

07年6月11日

(1)  怎么建三张表的联合left join结果却都在一个视图里显示的这样的视图

解释一下上面这个是什么意思吧,有三张表

TsysDepartInf部门表

departId   int   (4)    主键    

departParentId    int     (4)    父结点       (下面的继续讨论时加的字段)

departname     varchar(50)  部门名称  

departIsEnd     varchar(2)  是否是叶子节点

isDel     varchar(2)  是否删除

TsysUserInf用户表

userId     int     (4)  主键

username   varchar(50)  用户名称

TuserInf2TDept部门用户关联表

id    int    (4)   主键

departId    int   (4)  部门表主键

userId     int     (4)  用户表主键

根据需求,要把部门和用户的信息的结果都放在一个视图里面,然后用ajax的第三方开源树遍历这些信息,在一棵树中显示这些信息.恩,该怎么解决?建视图吧

(SELECT dbo.TsysDepartInf.departId tid, dbo.TsysDepartInf.departName tname,
      dbo.TsysDepartInf.departIsEnd tisend, dbo.TsysDepartInf.isDel tisdel
FROM dbo.TsysDepartInf left join dbo.TuserInf2TDept on dbo.TsysDepartInf.departId = dbo.TuserInf2TDept.departId)
union
(select dbo.TsysUserInf.userId tid, dbo.TsysUserInf.userName tname, null tisend, null tisdel
from dbo.TsysUserInf left join dbo.TuserInf2TDept on dbo.TsysUserInf.userId = dbo.TuserInf2TDept.userId)

这是建视图的语句,但是SQLServer2000里,通过图形界面建视图,无法保存,会报"视图无法解析union"的错;但是在它的查询分析器里,执行这句话确是完全可行的!

那么,只要把上面的语句加句话放在查询分析器里执行了

CREATE VIEW dbo.V_SHOW
  AS

SELECT dbo.TsysDepartInf.departId tid, dbo.TsysDepartInf.departName tname,
      dbo.TsysDepartInf.departIsEnd tisend, dbo.TsysDepartInf.isDel tisdel
FROM dbo.TsysDepartInf left join dbo.TuserInf2TDept on dbo.TsysDepartInf.departId = dbo.TuserInf2TDept.departId
union
select dbo.TsysUserInf.userId tid, dbo.TsysUserInf.userName tname, null tisend, null tisdel
from dbo.TsysUserInf left join dbo.TuserInf2TDept on dbo.TsysUserInf.userId = dbo.TuserInf2TDept.userId

蓝色的代码是标准的建视图语句!当在查询分析器里执行完这个语句,点击"视图"------->右键"刷新",就会看到所建的视图已经存在了,如果偏要"视图"------>右键"新建视图",那么就会报"视图无法解析union"的错.这样,你无法建的!

另外还要注意:

1>>>青色的标记,这些都是别名,只要别名一样,结果就会在一起的,部门表要显示的字段又比用户表多,当用户表没有与部门表对应的字段时,就要设为null +别名,而不是部门表中真正的字段名,如:dbo.TsysDepartInf.departIsEnd dbo.TsysDepartInf.isDel 这两个字段!

2>>>必须保证对应字段类型的一致性,否则会出错!

3>>>union 与union  all  的区别:

         union连接的时候,查询的结果没有重复

         union  all  连接的时候,查询结果是有重复

看看结果吧:  哦,先说说我表里有的数据!

我的部门表有的数据信息是

departid       departName      departIsEnd       isDel

    1                   zhang                       0                       0

    2                   wang                        0                       0

    3                    jiang                        0                       0

用户表的信息是

   userId          username

      5                   zhang

      6                   wang

      7                   jiang

      8                   test

运行视图的结果:

    tid                   tname                   tisend                    tisdel

     1                   zhang                          0                           0

     2                   wang                           0                           0

     3                   jiang                            0                           0    

     5                   zhang                         null                      null

     6                   wang                          null                      null

     7                   jiang                           null                      null

     8                   test                             null                      null

    继续讨论这颗树的显示问题:下面是我对这颗树的视图优化和hibernate映射问题的解决

从这颗树显示的角度考虑上面建的视图吧。上面的视图少了一个parentid也就是这颗树的父结点,少了这个,嘿嘿。。。这颗树是无法显示出层级关系的,这是个大问题。刚才又优化了一下视图,这个问题就解决了,比较perfect的视图了。

树的显示问题:所有的用户都应该在这个部门下面,而且用户下面不再有任何层级关系了,也就是“所有的用户都是这颗树的叶子结点”。

还有就是部门下面可以在添加部门的,所以添加部门的时候判断是否是叶子结点,如果是,那就javascript的alert一个提示信息就OK了!

基于上面的考虑,只能重新改写一下上面的视图了,如下:

CREATE VIEW dbo.VajaxDepartTree  (把视图改成这个名字了)
  AS
SELECT dbo.TsysDepartInf.departId tid, dbo.TsysDepartInf.departName tname,
      dbo.TsysDepartInf.departIsEnd tisend, dbo.TsysDepartInf.isDel tisdel, dbo.TsysDepartInf.departParentId tdepartparentid
FROM dbo.TsysDepartInf left join dbo.TuserInf2TDept on dbo.TsysDepartInf.departId = dbo.TuserInf2TDept.departId
union
select dbo.TsysUserInf.userId tid, dbo.TsysUserInf.userName tname, tisend=1, null tisdel, dbo.TsysDepartInf.departId tdepartparentid
from  dbo.TsysUserInf left join dbo.TuserInf2TDept on dbo.TsysUserInf.userId = dbo.TuserInf2TDept.userId
      left join dbo.TsysDepartInf on dbo.TsysDepartInf.departId = dbo.TuserInf2TDept.departId

青色的为改动后的,因为0在ajax这颗树里不是叶子结点,1是叶子结点,用户必须是叶子结点,所以给别名 tisend=1赋值为1就行了,这样,查出的数据中关于用户信息中的tisend就直接赋值为1了,不用在程序里判断了。

因为用户和部门是有对应关系的,所以又加了dbo.TsysDepartInf.departId tdepartparentid,这样每一个用户都可以对应着部门id了,别名是tdepartparentid这个别名的真正字段是部门表的departId,而不是dbo.TsysDepartInf.departParentId tdepartparentid 部门表的departParentId。这样做是为了兼顾这个视图的查询结果是树型的结构!很重要!

这样,这个视图就比较perfect了。

为了看效果,我把关联表中的也加了信息

     userId     departId

         8                 1

         7                  2

         6                 3

userId 5没有做关联。

运行结果:

 tid                   tname                   tisend                    tisdel            tdeparparentid

 

 

 

     1                   zhang                          0                           0                           0

     2                   wang                           0                           0                           0

     3                   jiang                            0                           0                           0

     6                   wang                          1                       null                           3

     7                   jiang                           1                      null                            2

     8                   test                             1                       null                           1

终于出来了,累死我了!当部门的tdeparparentid是0的时候,表示他是根目录!

这样可以用hibernate生成hbm配置文件了

<hibernate-mapping>
    <class name="com.yliso.hibernate.po.VajaxDepartTree" table="VajaxDepartTree" schema="dbo" catalog="yliso">
            <id name="tid" type="integer">
             <column name="tid" />             
           </id>
            <property name="tname" type="string">
                <column name="tname" length="32" />
            </property>
            <property name="tisend" type="string">
                <column name="tisend" length="1" />
            </property>
            <property name="tisdel" type="string">
                <column name="tisdel" length="2" />
            </property>
            <property name="tdepartparentid" type="integer">
                <column name="tdepartparentid" />
            </property>      
    </class>
</hibernate-mapping>

视图没有主键,会多一个PO复合主键的类,把那个类干掉!配置文件里把别名tid设为主键就行了,因为tid是没有重复的,而且tid里面有departId和userId的数据,你根据departId和userId中任何一个做主键,都不是最好的办法!还是以tid做主键最好!好了,终于解决了。。。。。。这个问题昨天搞到半夜,今天又考虑得很全面,折腾一上午,累了。吃饭去了,不过问题很经典,解决了很有成就感,开心!

忘了说了,要直接在查询分析器里运行生成这个视图,视图的编译器不认union,无法建!

而且直接在查询分析器里运行生成这个视图这样生成的视图,在视图里图形界面是看不到表及表关系,图形界面看不到哪个字段是显示还是没有显示的!原因很简单,SQLServer 2000里面的视图的设计器不支持union

07年6月20日

继续说说这颗树,上面的解决办法是可以显示的,但是今天说的却都是缺点,以至于我这颗树不得不在项目中废掉另建视图解决,但是新建的视图仍然无法在树里显示出根据文件分配用户的关联。。。。郁闷ing。。。。

这颗树结合现在的ajaxa动态树的第3方控件,是彻底的失败了。。。因为结合第3方的控件,当部门A下面还有部门B,并且部门A下面有用户C,部门B下面有用户C的时候,把这个全选中,传过去的Id里面有第3方控件的一个随机数,并且原来根据","号传过去的id中,有类似这样的情况:335,336,11187965_337,111199999_338,332,111188888_331,231,266,这样的串出现,都是随机的,再结合需求的变化。。。废了这颗树。如果不用第3方的控件这颗树是没有问题的。。。。。。