sql - 具有动态选择语句的表值函数
问题描述
创建应返回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 分钟的时间,所以我正在通过创建函数来寻找替代方案。
解决方案
在文档中明确表示:
用户定义的函数不能使用动态 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 的特殊情况。我可以向您展示如何做到这一点,但最好坚持使用存储过程。
推荐阅读
- python - 用熊猫中的默认值替换
- c# - 为 Linq 中的分组项目添加编号
- python - Django 可交换模型外键
- c# - 即使我对特定位置进行硬编码,角色也会移动到错误的位置
- android - Tron 令牌发送两位数不起作用
- javascript - 在 useState Hook 中使用 SWR 数据
- php - 如何在多维数组中获取以字符串开头的数组键?
- django - 如何在 django admin 中显示 manytomanyfields
- php - 是否可以使用(使用 PHP)先前在 mysql CLI 中声明的准备好的语句?
- python - 如何在 Python 中根据日期处理文件?