下午遇到一个需求,写一个SQL Function根据一些子结点的OID找到指定层级的父结点.OID,子结点的OID如**,**,**所示.
又一次领略了用SQL写函数和存储过程的别扭,也许是自己用惯了VS.NET随便点点就可以写程序的方式.唉,SQL里居然没有split,郁闷地找了半天,最后用SubString和CharIndex自己模仿了Split的功能.
写出的函数结果如下:
/**/
/*********************根据子结点寻找父结点*************************************/
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**/
/*入口参说明:@SUNOIDS 为待寻找父结点的子结点 形式必须为 OID,OID,OID,OID的形式
@LEVEL 指定的层级 比如1,2,3
*/
![None.gif](/Images/OutliningIndicators/None.gif)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**/
/*返回参数 @Rusult 得到的父结点集合*/
CREATE
FUNCTION
GETPARENTOID(
@SUNOIDS
VARCHAR
(
8000
),
@LEVEL
INT
)
RETURNS
@RESULT
TABLE
(PARENTOID
VARCHAR
(
40
))
AS
BEGIN
DECLARE
@SUNOID
VARCHAR
(
40
)
DECLARE
@ROWCOUNT
INT
DECLARE
@STARTPOSITION
INT
--
-SUBSTRING的开始地方
DECLARE
@FLAG
INT
--
-标志循环是否结束
DECLARE
@SUNOLDOID
VARCHAR
(
40
)
--
-保持原有值用于比较
SET
@ROWCOUNT
=
1
SET
@STARTPOSITION
=
1
SET
@FLAG
=
1
![None.gif](/Images/OutliningIndicators/None.gif)
--
------------如果长度小于一个OID的长度,说明调用方不满足调用要求,直接返回--------
IF
(
LEN
(
@SUNOIDS
)
<
36
)
RETURN
![None.gif](/Images/OutliningIndicators/None.gif)
WHILE
@FLAG
<>
0
BEGIN
SET
@ROWCOUNT
=
1
--
--保证SQL语句会查询一次
--
--------------------得到每个结点------------------
SET
@SUNOID
=
SUBSTRING
(
@SUNOIDS
,
@STARTPOSITION
,
36
)
SET
@FLAG
=
CHARINDEX
(
'
,
'
,
@SUNOIDS
,
@FLAG
+
1
)
SET
@STARTPOSITION
=
@FLAG
+
1
--
--------------保留该结点-------------
SET
@SUNOLDOID
=
@SUNOID
WHILE
@ROWCOUNT
<>
0
BEGIN
SELECT
@SUNOID
=
PARENTOID
FROM
TBL_SALEORG
WHERE
OID
=
@SUNOID
AND
SOG_BIZLEVEL
>
@LEVEL
SET
@ROWCOUNT
=
@@ROWCOUNT
END
--
-----------如果最终得到的结点跟原来结点不同,说明找到了指定层级的父结点,添加到
IF
(
@SUNOLDOID
<>
@SUNOID
)
INSERT
INTO
@RESULT
VALUES
(
@SUNOID
)
END
RETURN
END
程序倒是很简单,就是SQL一些稀奇古怪的东西搞得烦死人.@@ROWCOUNT 动不动就要自己变,害我浪费一个变量存了一下,这个程序还需要扩展,不过基本实现了功能,懒得动了,简直烦死人.还是等着在SQL Server2005里用C#写算了.