Табличная функция с динамическим оператором выбора - PullRequest
0 голосов
/ 05 ноября 2019

Создание пользовательской табличной функции, которая должна возвращать select union all динамический запрос.

У меня есть таблица tbl_tablesinfo, которая содержит имена таблиц tbl1, tbl2, tbl3 и т. д. во всех около 3000 имен таблиц.

Я не хочу создавать представление, но функцию, которая должна возвращать 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

Я получаю сообщение об ошибке:

Неверный синтаксис рядом с 'НАЧАЛО'.

Причиной для этого является создание представления с 3kТаблицы становятся медленными и занимают около 30 минут времени, поэтому я ищу альтернативу, создавая функцию.

Ответы [ 2 ]

2 голосов
/ 05 ноября 2019

В документах ясно сказано, что:

Пользовательские функции не могут использовать динамический 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 голосов
/ 05 ноября 2019
  1. Вы не можете использовать динамический запрос в функции SQL ...
  2. Функции могут возвращать только скалярные значения или таблицы ...
  3. Вместо этого вы можете использовать хранимую процедуру. ..
...