Как создать представление, которое CROSS APPLYs представляет собой серию встроенных табличных UDF? - PullRequest
0 голосов
/ 26 октября 2018

Вот структура кода, на которую я смотрю:

CREATE VIEW [dbo].[View1]

    AS SELECT t1.[ID]        ,
              udf1.[Column1] ,
              udf1.[Column2] ,
              udf1.[Column3]

        FROM [Table1] t1
            CROSS APPLY [dbo].[UDF1] ( [dbo].[UDF2] ( t1.[ID] ) ) udf1

GO

[dbo].[UDF1] и [dbo].[UDF2] являются встроенными табличными функциями.

Я не помню точных деталей, но SSMS выдавал мне ошибки, когда я пытался использовать JOIN, и SO сказал мне, что мне нужно использовать CROSS APPLY, чтобы исправить это - я думаю, что это был правильный выбор?

В любом случае, главная проблема, с которой я столкнулся сейчас:

Не удалось найти ни столбец "dbo", ни пользовательскую функцию, ни агрегат "dbo.UDF2", либо имя неоднозначно.

... несмотря на то, что UDF2 явно существует: я вижу это в SSMS.

Я подозреваю, что настоящая проблема в том, что UDF2 передается в качестве параметра в UDF1.
UDF2 возвращает таблицу, и столбцы точно соответствуют табличному параметру, определенному для UDF1.

Но я думаю SQL Server не поддерживает этот синтаксис?
Нужно ли преобразовывать мое представление в многострочную табличную функцию, объявлять табличную переменную для получения результатов UDF2, а затем передавать эту табличную переменную в UDF1?

(P.S. Ошибки SQL Server - одни из наименее полезных, которые я когда-либо видел, на любом языке ...)

1 Ответ

0 голосов
/ 26 октября 2018

Вероятно, это будет иметь очень низкую производительность, но я думаю, что вам нужно использовать отдельный CROSS APPLY для каждой функции табличного значения. Я не думаю, что можно использовать содержимое, возвращаемое UDF2 в UDF1, поскольку UDF1 потребуется параметр типа таблицы, а UDF2 возвращает таблицу, но не тип таблицы.

Функции не могут возвращать типы таблиц, поэтому вам, вероятно, придется найти другое решение. Вы можете создать еще одну функцию, которая вставляет результаты UDF2 в тип таблицы и затем вызывает UDF1.

Если бы вы могли это сделать, это выглядело бы примерно так:

CREATE VIEW [dbo].[View1]
    AS SELECT t1.[ID]        ,
              udf1.[Column1] ,
              udf1.[Column2] ,
              udf1.[Column3]
        FROM [Table1] t1
            CROSS APPLY [dbo].[UDF2] ( t1.[ID] ) udf2
            CROSS APPLY [dbo].[UDF1] ( udf2 ) udf1
GO

Чтобы создать «еще одну функцию-обертку», она должна выглядеть так:

CREATE FUNCTION [dbo].[UDF3](
    @id INT -- data type for t1.ID
) RETURNS @t TABLE (
    -- ... Your columns here ...
) 
AS
BEGIN
    -- Your user defined Table Type
    DECLARE @udf2 UDF2_TABLE 
    INSERT @udf2 (... columns ...)
    SELECT udf2.* -- try to use exact column names instead of *
      FROM [Table1] t1
         CROSS APPLY [dbo].[UDF2]( t1.[ID] )

    -- I'm not really sure this is possible either
    INSERT @t (... columns ...)
    SELECT udf1.*
      FROM [dbo].[UDF1](@udf2) udf1

    RETURN;
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...