具有动态选择语句的表值函数

问题描述 投票:0回答:2

创建一个用户定义的表值函数,该函数应返回select union all动态查询。

我有表tbl_tablesinfo,其中包含大约3000个表名中的表名tbl1tbl2tbl3等。

我不想创建视图,但需要通过执行select * from返回所有表的union all函数。

我的尝试:

CREATE FUNCTION udf_alldata()
RETURNS TABLE
AS
BEGIN
    DECLARE @Var VARCHAR(MAX) = ''

    SELECT 
        @Var = STUFF((SELECT ' SELECT * FROM [' + tbl.TableNames + '] UNION ALL'
                      FROM [TestDB].SYS.TABLES tb 
                      INNER JOIN [TestDB].dbo.[tbl_tablesinfo] tbl ON tb.name = tbl.TableNames
                      FOR XML PATH('')), 1, 1, '');

    SET @var = LEFT(@var, LEN(@var) - 10);

    EXEC @var 

    RETURN
END

我遇到错误:

“ BEGIN”附近的语法不正确。

这样做的原因是使用3k表创建视图的速度越来越慢,并且大约需要30分钟的时间,因此我正在通过创建函数来寻找替代方法。

sql sql-server tsql sql-server-2012
2个回答
0
投票

docs中清楚地说,那:

用户定义的函数不能使用动态SQL或临时表。允许使用表变量。

这意味着您需要使用存储过程,这还不错,因为您仍然可以在表中插入数据:

INSERT INTO @Table
EXEC [dbo].[stored_procedured_name]

INSERT INTO #Table
EXEC [dbo].[stored_procedured_name]

所以,在您的情况下,您将拥有:

CREATE PROCEDURE udf_alldata
AS
BEGIN
    DECLARE @Var VARCHAR(MAX) = ''

    SELECT 
        @Var = STUFF((SELECT ' SELECT * FROM [' + tbl.TableNames + '] UNION ALL'
                      FROM [TestDB].SYS.TABLES tb 
                      INNER JOIN [TestDB].dbo.[tbl_tablesinfo] tbl ON tb.name = tbl.TableNames
                      FOR XML PATH('')), 1, 1, '');

    SET @var = LEFT(@var, LEN(@var) - 10);

    EXEC sp_executesql @var 

    RETURN
END

注意,实际上您可以执行dynamic T-SQL in function,但这是使用SQL CLR的特殊情况。我可以向您展示如何执行此操作,但是最好使用存储过程。


0
投票
 1. You can't use Dynamic Query in SQL Function...

 2. Functions can return only Scalar Values, or Tables...

 3. Instead you can use Stored Procedure...
© www.soinside.com 2019 - 2024. All rights reserved.