当我们在SQL中使用用户定义的函数返回表时,为什么我们不使用begin和end?

时间:2016-09-02 09:06:12

标签: sql-server tsql

当我们在SQL中使用用户定义的函数返回表时,我们为什么不使用BEGINEND

e.g。

CREATE FUNCTION Customers
(@minId int)
RETURNS TABLE 
AS
RETURN(SELECT *
    FROM   TrackingItem ti
    WHERE  ti.Id >= @minId)

工作

CREATE FUNCTION Customers
(@minId int)
RETURNS TABLE 
AS
BEGIN
   RETURN(SELECT *
   FROM   TrackingItem ti
   WHERE  ti.Id >= @minId)
END

不起作用

3 个答案:

答案 0 :(得分:1)

您没有标记DBMS,但是根据您的语法,我猜这是SQL Server ...

好方法:内联TVF

内嵌语法(不包含BEGIN...END)的工作方式类似于带参数的VIEW。在使用时,它将由查询优化器完全内联 - 就像代码是在使用函数的地方(几乎)编写的一样。这意味着:完全使用索引,统计数据,追逐结果......

但是 - 这在所有情况下都是不可能的(但在大多数情况下) - 你必须能够在一个语句中编写完整的逻辑。

糟糕的方法:多语句TVF

第二个示例需要一个适合您想要返回的结果的表定义。您的代码必须对此虚拟表使用INSERT,然后将其返回。您的示例中缺少这个。

如果可能的话,绝对应该避免这种方法。查询优化器将无法查看此代码以预测结果。它将无法以内联查询的方式使用临时/缓存结果或索引/统计信息。

答案 1 :(得分:0)

第一个,没有 BEGIN和END被称为“内联表值函数”。您只能在函数体内部使用单个语句来立即返回结果集。

第二个 BEGIN和END称为“多语句表值函数”。您可以在函数体内部有多个语句,然后在底部有一个RETURN语句来返回结果集。这允许您例如填充TABLE变量然后返回它。

内联表值函数可以被视为一个视图 - 在它扩展到调用查询中,基础表的统计信息可用于提供更好的执行计划。

多语句值函数不会像这样展开,并且在创建执行计划时不会从相同的好处中受益。

因此,最好避免使用多语句表值函数,而更喜欢内联函数,以获得这些好处并避免潜在的性能问题。

答案 2 :(得分:0)

您可以使用这种方式,返回表类型信息,您必须使用列定义表并通过表返回数据:尝试以下假设您有2列id和名称:

CREATE FUNCTION Customers(@minId INT)
RETURNS @@table TABLE (id INT, NAME VARCHAR(20)) 
AS
BEGIN
   INSERT INTO @@table
   SELECT id, name
   FROM TrackingItem ti
   WHERE ti.Id >= @minId

   RETURN
END