我真的可以使用一些帮助来编写一个使用以下逻辑的多语句表值函数:
到目前为止,这就是我所拥有的:
CREATE FUNCTION dbo.CheckAccess
(@UserName varchar(30))
RETURNS @AccessTable TABLE (User varchar(max), Access varchar(max))
AS
BEGIN
IF LEFT(@UserName,1) = 'A'
INSERT INTO @AccessTable
SELECT
CASE
WHEN EXISTS (SELECT User, Access FROM dbo.AccessTable1 WHERE User = @UserName)
THEN (SELECT User, Access FROM dbo.AccessTable1 WHERE User = @UserName)
ELSE (SELECT @UserName User, 'No Access' Access)
END
ELSE
INSERT INTO @AccessTable
SELECT
CASE
WHEN EXISTS (SELECT User, Access FROM dbo.AccessTable2 WHERE User = @UserName)
THEN (SELECT User, Access FROM dbo.AccessTable2 WHERE User = @UserName)
ELSE (SELECT @UserName User, 'No Access' Access)
END
RETURN
END;
不确定我在这里缺少什么,但我收到以下错误:
Msg 116, Level 16, State 1, Procedure CheckAccess, Line 90
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Msg 116, Level 16, State 1, Procedure CheckAccess, Line 92
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Msg 213, Level 16, State 1, Procedure CheckAccess, Line 11
Column name or number of supplied values does not match table definition.
我知道如何使用临时表在存储过程中相当容易地完成此操作,但由于它们不是函数中的选项,因此我遇到了一些困难。如果有人能提出一些建议,我真的很感激。提前谢谢。
答案 0 :(得分:1)
您可以使用@@rowcount
服务器变量简化您的功能:
CREATE FUNCTION dbo.CheckAccess
(@UserName varchar(30))
RETURNS @AccessTable TABLE (User varchar(max), Access varchar(max))
AS
BEGIN
IF LEFT(@UserName,1) = 'A'
INSERT INTO @AccessTable
SELECT User, Access FROM dbo.AccessTable1 WHERE User = @UserName
ELSE
INSERT INTO @AccessTable
SELECT User, Access FROM dbo.AccessTable2 WHERE User = @UserName
--@@rowcount gives number of records inserted/affected from immediately previous query
IF @@RowCount = 0
INSERT INTO @AccessTable
SELECT @UserName User, 'No Access' Access
RETURN
END;
答案 1 :(得分:0)
而不是像这样的布尔检查
EXISTS (SELECT User, Access FROM dbo.AccessTable1 WHERE User = @UserName)
试
EXISTS (SELECT 1 FROM dbo.AccessTable1 WHERE User = @UserName)
一般来说EXISTS表达式不需要特定的结果,它只需要检查是否返回了NULL,因为没有找到行或者无论是什么都可以返回。它是一个布尔表达式,其值为yes或no。 '1'足以满足这一目的。前两个错误消息是关于此的。
下一个问题是CASE表达式根据定义只能定义一个字段和一个字段。它无法返回所需的两个字段。这是最后一条错误消息的可能性,该函数被定义为返回两个字段。您现在可以用逗号分隔两个CASE表达式。
我建议你的逻辑采用不同的方法:在你的IF语句中做sub-IFs,比如嵌套的IF。我没有测试过这个,只是一个想法:
IF LEFT(@UserName,1) = 'A'
IF EXISTS (SELECT 1 FROM dbo.AccessTable1 WHERE User = @UserName)
INSERT INTO @AccessTable
SELECT User, Access FROM dbo.AccessTable1 WHERE User = @UserName
ELSE (SELECT @UserName User, 'No Access' Access)
ELSE
IF EXISTS (SELECT 1 FROM dbo.AccessTable2 WHERE User = @UserName)
INSERT INTO @AccessTable
SELECT User, Access FROM dbo.AccessTable2 WHERE User = @UserName
ELSE (SELECT @UserName User, 'No Access' Access)
或其他可能表现更好的想法,但我不确定这是否符合您对“Access”字段100%的要求。如果表中存在@username,那么 allways 是否在Access-field中是否满足?
IF LEFT(@UserName,1) = 'A'
SELECT
ISNULL(User,@UserName) User
,ISNULL(Access,'No Access') Access
FROM dbo.AccessTable1 WHERE User = @UserName
ELSE
SELECT
ISNULL(User,@UserName) User
,ISNULL(Access,'No Access') Access
FROM dbo.AccessTable2 WHERE User = @UserName
另外一句话:IF(也是ELSE)只考虑以下一个陈述。如果要运行多个语句,您需要通过BEGIN和END来封装它们,如此
IF @fact=1
BEGIN
statement 1
.
.
statement n
END
ELSE
BEGIN
statement 1
.
.
statement n
END