创建一个用户定义的表值函数,该函数应返回select
union all
动态查询。
我有表tbl_tablesinfo
,其中包含大约3000个表名中的表名tbl1
,tbl2
,tbl3
等。
我不想创建视图,但需要通过执行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分钟的时间,因此我正在通过创建函数来寻找替代方法。
在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的特殊情况。我可以向您展示如何执行此操作,但是最好使用存储过程。
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...