SQL 递归 udf 总是 returns null
SQL recursive udf always returns null
Create Table Employees
(
Employee varchar(10),
Manager varchar(10)
);
Insert into Employees
values
('Charlie',null),
('Peter','James'),
('Elai',null),
('Graham','Emanuel'),
('Amanda','Charlie'),
('Sen','Graham'),
('Emanuel',null),
('James','Amanda'),
('Elai',null),
('Victor','Elai');
上方 "Employees" table 包含员工和员工的经理姓名。尝试使用以下函数检索员工的逗号分隔层次结构时,结果始终为空。
例如:
员工 'Victor'
、hierarchy/result 应该是 "Victor, Elai"
。
谁能指出我在下面的 UDF 中做错了什么。
Create Function EmployeeHierarchy(@employeeName varchar(20))
Returns varchar(100)
AS
Begin
Declare @commaSeparatedHierarchy varchar(100);
Declare @manager varchar(20);
if(@employeeName is not null)
Begin
Select @manager=Manager from Employees where Employee=@employeeName;
Set @commaSeparatedHierarchy=dbo.EmployeeHierarchy(@manager)+','+@manager;
End
return @commaSeparatedHierarchy;
End;
首先,您不想将其创建为标量函数。它们的性能非常糟糕,您创建的任何 udf 都应该创建为内联 table 值函数。以下内容应该可以满足您的需求...
-- the test data...
USE tempdb;
GO
IF OBJECT_ID('tempdb.dbo.Employee', 'U') IS NOT NULL
DROP TABLE dbo.Employee;
CREATE TABLE dbo.Employee (
Employee varchar(10),
Manager varchar(10)
);
INSERT dbo.Employee (Employee, Manager) VALUES
('Charlie',null),
('Peter','James'),
('Elai',null),
('Graham','Emanuel'),
('Amanda','Charlie'),
('Sen','Graham'),
('Emanuel',null),
('James','Amanda'),
('Elai',null),
('Victor','Elai');
SELECT * FROM dbo.Employee e;
iTVF 代码...
CREATE FUNCTION dbo.EmployeeHierarchy
(
@employeeName varchar(20)
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH
cte_Recur AS (
SELECT
CSH = CAST(CONCAT(e.Employee, ', ' + e.Manager) AS VARCHAR(1000)),
e.Manager,
NodeLevel = 1
FROM
dbo.Employee e
WHERE
e.Employee = @employeeName
UNION ALL
SELECT
CSH = CAST(CONCAT(r.CSH, ', ' + e.Manager) AS VARCHAR(1000)),
e.Manager,
NodeLevel = r.NodeLevel + 1
FROM
dbo.Employee e
JOIN cte_Recur r
ON e.Employee = r.Manager
WHERE
e.Manager IS NOT NULL
)
SELECT
commaSeparatedHierarchy = MAX(r.CSH)
FROM
cte_Recur r;
GO
示例执行...
SELECT
eh.commaSeparatedHierarchy
FROM
dbo.EmployeeHierarchy('peter') eh;
...结果...
commaSeparatedHierarchy
------------------------------
Peter, James, Amanda, Charlie
Create Table Employees
(
Employee varchar(10),
Manager varchar(10)
);
Insert into Employees
values
('Charlie',null),
('Peter','James'),
('Elai',null),
('Graham','Emanuel'),
('Amanda','Charlie'),
('Sen','Graham'),
('Emanuel',null),
('James','Amanda'),
('Elai',null),
('Victor','Elai');
上方 "Employees" table 包含员工和员工的经理姓名。尝试使用以下函数检索员工的逗号分隔层次结构时,结果始终为空。
例如:
员工 'Victor'
、hierarchy/result 应该是 "Victor, Elai"
。
谁能指出我在下面的 UDF 中做错了什么。
Create Function EmployeeHierarchy(@employeeName varchar(20))
Returns varchar(100)
AS
Begin
Declare @commaSeparatedHierarchy varchar(100);
Declare @manager varchar(20);
if(@employeeName is not null)
Begin
Select @manager=Manager from Employees where Employee=@employeeName;
Set @commaSeparatedHierarchy=dbo.EmployeeHierarchy(@manager)+','+@manager;
End
return @commaSeparatedHierarchy;
End;
首先,您不想将其创建为标量函数。它们的性能非常糟糕,您创建的任何 udf 都应该创建为内联 table 值函数。以下内容应该可以满足您的需求...
-- the test data...
USE tempdb;
GO
IF OBJECT_ID('tempdb.dbo.Employee', 'U') IS NOT NULL
DROP TABLE dbo.Employee;
CREATE TABLE dbo.Employee (
Employee varchar(10),
Manager varchar(10)
);
INSERT dbo.Employee (Employee, Manager) VALUES
('Charlie',null),
('Peter','James'),
('Elai',null),
('Graham','Emanuel'),
('Amanda','Charlie'),
('Sen','Graham'),
('Emanuel',null),
('James','Amanda'),
('Elai',null),
('Victor','Elai');
SELECT * FROM dbo.Employee e;
iTVF 代码...
CREATE FUNCTION dbo.EmployeeHierarchy
(
@employeeName varchar(20)
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH
cte_Recur AS (
SELECT
CSH = CAST(CONCAT(e.Employee, ', ' + e.Manager) AS VARCHAR(1000)),
e.Manager,
NodeLevel = 1
FROM
dbo.Employee e
WHERE
e.Employee = @employeeName
UNION ALL
SELECT
CSH = CAST(CONCAT(r.CSH, ', ' + e.Manager) AS VARCHAR(1000)),
e.Manager,
NodeLevel = r.NodeLevel + 1
FROM
dbo.Employee e
JOIN cte_Recur r
ON e.Employee = r.Manager
WHERE
e.Manager IS NOT NULL
)
SELECT
commaSeparatedHierarchy = MAX(r.CSH)
FROM
cte_Recur r;
GO
示例执行...
SELECT
eh.commaSeparatedHierarchy
FROM
dbo.EmployeeHierarchy('peter') eh;
...结果...
commaSeparatedHierarchy
------------------------------
Peter, James, Amanda, Charlie