引言:
Oracle的PLSQL有现成的递归函数并可以显示级别和递归路径,但是SQL Server下如何实现呢?看了一些资料后,知道用CTE可以实现,可是我还想获取到递归路径(PLSQL下使用SYS_CONNECT_BY_PATH获取)
问题:
WITH Employees AS
(
SELECT EmployeeKey,
ParentEmployeeKey,
FullName,
Title,
1 AS EmployeeLevel,
FullName as namepath
FROM DimEmployee
WHERE ParentEmployeeKey IS NULL
UNION ALL
SELECT e.EmployeeKey,
e.ParentEmployeeKey,
e.FullName,
e.Title,
es.EmployeeLevel + 1 AS EmployeeLevel,
es.namepath +'->'+e.fullname as namepath
FROM DimEmployee AS e
INNER JOIN Employees AS es
ON es.EmployeeKey = e.ParentEmployeeKey
)
SELECT *
FROM Employees
ORDER BY EmployeeLevel,FullName;
报错:
消息 240,级别 16,状态 1,第 1 行
在递归查询 "Employees" 的列 "namepath" 中,定位点类型和递归部分的类型不匹配。
解决办法:
1、对列做显式类型转换;
2、with中第一条select的字段长度一定要足够长。
WITH Employees AS
(
SELECT EmployeeKey,
ParentEmployeeKey,
FullName,
Title,
1 AS EmployeeLevel,
CAST(FullName as nvarchar(1000)) as namepath
FROM DimEmployee
WHERE ParentEmployeeKey IS NULL
UNION ALL
SELECT e.EmployeeKey,
e.ParentEmployeeKey,
e.FullName,
e.Title,
es.EmployeeLevel + 1 AS EmployeeLevel,
CAST(es.namepath +'->'+e.fullname as nvarchar(1000)) as namepath
FROM DimEmployee AS e
INNER JOIN Employees AS es
ON es.EmployeeKey = e.ParentEmployeeKey
)
SELECT *
FROM Employees
ORDER BY EmployeeLevel,FullName;
参考资料:
http://blog.itpub.net/81227/viewspace-743137/
http://www.flybi.net/blog/lovezsr/2259
http://www.cnblogs.com/CareySon/archive/2011/12/12/2284740.html
DimEmployee:
IF OBJECT_ID('DimEmployee','U') IS NOT NULL
DROP TABLE DimEmployee
SELECT EmployeeKey,
ParentEmployeeKey,
EmployeeNationalIDAlternateKey,
CASE WHEN ISNULL(MiddleName,'') = '' THEN FirstName +' '+ LastName
ELSE FirstName +' '+ MiddleName +' '+LastName
END AS FullName,
Title
INTO DimEmployee
FROM AdventureWorksDW2008R2.dbo.DimEmployee