为什么在使用SELECT时我必须使用带有标量函数的模式(dbo.xxx)而不是在使用EXEC时?
DECLARE @ReplicationGroup nvarchar(255) = 'Replication Configuration';
SELECT dbo.fnGetReplicationGroupID(@ReplicationGroup) -- Works but I have to keep dbo.
EXEC fnGetReplicationGroupID @ReplicationGroup -- Works without dbo.
select dbo.fnIsDebugLoggingEnabled(); -- Works but I have to keep dbo.
EXEC fnIsDebugLoggingEnabled -- Works without dbo.
答案 0 :(得分:2)
SQL Server具有3 different types of functions:标量,表值和多语句表值。标量函数可以在允许标量表达式的地方使用,也可以在EXECUTE
语句中使用。只要允许表值表达式,不包含EXECUTE
语句,就可以使用表值函数和多语句表值函数。例子:
CREATE FUNCTION dbo.fnScalarFunctionExample(@value int)
RETURNS bit
AS
BEGIN
RETURN @value;
END;
GO
CREATE FUNCTION dbo.fnInlineTableValuedFunction (@value int)
RETURNS TABLE
AS
RETURN
(
SELECT @value AS Value
);
GO
CREATE FUNCTION dbo.fnMultiStatementTableValuedFunction (@value int)
RETURNS @Table TABLE
(
Value int NOT NULL
)
AS
BEGIN
INSERT INTO @Table VALUES(@value);
RETURN;
END;
GO
--scalar functions can be called with EXEC or wherever in a scalar experession is permitted
DECLARE @ReturnValue int;
EXEC @ReturnValue = dbo.fnScalarFunctionExample 1;
PRINT @ReturnValue;
GO
SELECT dbo.fnScalarFunctionExample(1);
GO
SELECT 1 WHERE dbo.fnScalarFunctionExample(1) = 1;
GO
--table-valued functions are invoked from a SELECT query
SELECT * FROM dbo.fnInlineTableValuedFunction(1);
SELECT * FROM dbo.fnMultiStatementTableValuedFunction(1);
GO
从语法上讲,在调用除EXECUTE
语句之外的函数时,指定括号(如果没有参数,则为空)。 Parens未指定EXECUTE
,参数(如果有)作为命名或位置参数提供,就像执行存储过程一样。
我经常看不到在{@ 1}}中使用EXECUTE
调用的标量函数,因为总是可以使用SELECT
。
修改强>
根据文档,有必要(至少)使用2部分名称对模式函数进行模式限定。至于为什么这是必要的,我认为这是为了避免与可能具有相同名称的系统功能产生歧义。