Object_ID 中不同类型的函数
Different types of Function in Object_ID
创建函数时,我倾向于在创建前先检查是否存在
IF Object_ID(N'myfunc', N'IF') IS NOT NULL
DROP FUNCTION myfunc
GO
CREATE FUNCTION myfunc...
有几种object_id功能需要检查:
FN = SQL scalar function
IF = SQL inline table-valued function
TF = SQL table-valued-function
FT = Assembly (CLR) table-valued function
我有一些问题:
'IF'、'TF'和[=32有什么区别=]'FT' 输入 ?
使用起来很容易出错
IF Object_ID(N'myFunc', 'IF') IS NOT NULL
有时函数是标量,其他情况下它是 table 值等。所以我可能会错过正确的类型检查。
我看到有人推荐
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'myfunc') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
是否足以检查所有类型的函数?你有什么建议?
1) IF 与多行 TF 与 CLR TF
内联Table值函数
像宏一样操作,非常高效,可以像参数化视图一样处理
CREATE FUNCTION dbo.name(@param INT)
RETURNS TABLE
AS
RETURN
SELECT ...
FROM tab t
WHERE t.Col = @param;
GO
多语句Table值函数
更灵活,如果需要,您可以执行许多中间步骤,但它会比 IF 慢。
CREATE FUNCTION dbo.name()
RETURNS @Result TABLE
(Col_name INT NOT NULL,
...
)
AS
BEGIN
/* Many operations */
INSERT @Result
SELECT *
FROM ...
RETURN
END
GO
CLR Table-值函数
Transact-SQL table-valued functions materialize the results of calling
the function into an intermediate table. Since they use an
intermediate table, they can support constraints and unique indexes
over the results. These features can be extremely useful when large
results are returned.
In contrast, CLR table-valued functions represent a streaming
alternative. There is no requirement that the entire set of results be
materialized in a single table. The IEnumerable object returned by the
managed function is directly called by the execution plan of the query
that calls the table-valued function, and the results are consumed in
an incremental manner. This streaming model ensures that results can
be consumed immediately after the first row is available, instead of
waiting for the entire table to be populated. It is also a better
alternative if you have very large numbers of rows returned, because
they do not have to be materialized in memory as a whole. For example,
a managed table-valued function could be used to parse a text file and
return each line as a row.
2) 检查函数是否存在:
检查ROUTINES目录:
Returns one row for each stored procedure and function that can be
accessed by the current user in the current database.
IF EXISTS ( SELECT 1
FROM INFORMATION_SCHEMA.ROUTINES
WHERE Specific_schema = 'dbo'
AND specific_name = 'Foo'
AND Routine_Type = 'FUNCTION' )
添加架构名称并删除对象类型。为什么需要检查对象是否是一个函数?仔细想想:
if object_id(N'dbo.functionname') is not null
drop function dbo.functionname
go
create function dbo.functionname ...
... 将删除函数(如果存在),然后创建它。
如果已经有一个名为 "dbo.functionname" 的对象并且它不是函数,则删除将失败。但无论您是否检查 "dbo.functionname" 是否为函数,都是如此。
换句话说,如果有一个名为dbo.functionname
的TABLE(或任何其他非函数对象),那么
if object_id(N'dbo.functionname', N'IF') -- equates to false
drop function dbo.functionanme -- doesn't get run
go
create function dbo.functionname... -- generates error
将在 create
函数上失败(因为 table dbo.functionname 不会被删除)。
您不能拥有两个具有相同 schema.objectname 的对象。因此,如果您只检查 object_id(N'schema.objectname')
,应该没问题。
创建函数时,我倾向于在创建前先检查是否存在
IF Object_ID(N'myfunc', N'IF') IS NOT NULL
DROP FUNCTION myfunc
GO
CREATE FUNCTION myfunc...
有几种object_id功能需要检查:
FN = SQL scalar function
IF = SQL inline table-valued function
TF = SQL table-valued-function
FT = Assembly (CLR) table-valued function
我有一些问题:
'IF'、'TF'和[=32有什么区别=]'FT' 输入 ?
使用起来很容易出错
IF Object_ID(N'myFunc', 'IF') IS NOT NULL
有时函数是标量,其他情况下它是 table 值等。所以我可能会错过正确的类型检查。
我看到有人推荐
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'myfunc') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
是否足以检查所有类型的函数?你有什么建议?
1) IF 与多行 TF 与 CLR TF
内联Table值函数
像宏一样操作,非常高效,可以像参数化视图一样处理
CREATE FUNCTION dbo.name(@param INT)
RETURNS TABLE
AS
RETURN
SELECT ...
FROM tab t
WHERE t.Col = @param;
GO
多语句Table值函数
更灵活,如果需要,您可以执行许多中间步骤,但它会比 IF 慢。
CREATE FUNCTION dbo.name()
RETURNS @Result TABLE
(Col_name INT NOT NULL,
...
)
AS
BEGIN
/* Many operations */
INSERT @Result
SELECT *
FROM ...
RETURN
END
GO
CLR Table-值函数
Transact-SQL table-valued functions materialize the results of calling the function into an intermediate table. Since they use an intermediate table, they can support constraints and unique indexes over the results. These features can be extremely useful when large results are returned.
In contrast, CLR table-valued functions represent a streaming alternative. There is no requirement that the entire set of results be materialized in a single table. The IEnumerable object returned by the managed function is directly called by the execution plan of the query that calls the table-valued function, and the results are consumed in an incremental manner. This streaming model ensures that results can be consumed immediately after the first row is available, instead of waiting for the entire table to be populated. It is also a better alternative if you have very large numbers of rows returned, because they do not have to be materialized in memory as a whole. For example, a managed table-valued function could be used to parse a text file and return each line as a row.
2) 检查函数是否存在:
检查ROUTINES目录:
Returns one row for each stored procedure and function that can be accessed by the current user in the current database.
IF EXISTS ( SELECT 1
FROM INFORMATION_SCHEMA.ROUTINES
WHERE Specific_schema = 'dbo'
AND specific_name = 'Foo'
AND Routine_Type = 'FUNCTION' )
添加架构名称并删除对象类型。为什么需要检查对象是否是一个函数?仔细想想:
if object_id(N'dbo.functionname') is not null
drop function dbo.functionname
go
create function dbo.functionname ...
... 将删除函数(如果存在),然后创建它。
如果已经有一个名为 "dbo.functionname" 的对象并且它不是函数,则删除将失败。但无论您是否检查 "dbo.functionname" 是否为函数,都是如此。
换句话说,如果有一个名为dbo.functionname
的TABLE(或任何其他非函数对象),那么
if object_id(N'dbo.functionname', N'IF') -- equates to false
drop function dbo.functionanme -- doesn't get run
go
create function dbo.functionname... -- generates error
将在 create
函数上失败(因为 table dbo.functionname 不会被删除)。
您不能拥有两个具有相同 schema.objectname 的对象。因此,如果您只检查 object_id(N'schema.objectname')
,应该没问题。