Функция SnowFlake не возвращает данные и ошибки - PullRequest
0 голосов
/ 06 мая 2020

У меня есть функция, которая принимает 3 varchar входных данных и возвращает 1 varchar выходных.

Функция довольно хорошо работает на SQL сервере, но не в Snowflake. Я не понимаю, что случилось. Кажется, все в порядке.

Примечание: он отлично работает, когда передается строка, но не когда передается столбец. Я не уверен, почему он не принимает несколько строк ??

SELECT Get_Status_Descriptiontest('can', '1', '2')

Ниже приведен запрос:

with cte as (
    select 'CAN' as a, 1 as b
    union
    select 'Ban' as a, 2 as b
)
SELECT Get_Status_Descriptiontest(a, '1', '2'), *
FROM cte;

Выдает ошибку

SQL compliation error: Unsupported subquery type cannot be evaluated

Это это пример функции:

create or replace function Get_Status_Descriptiontest(Status_Code1 varchar, Status_Code2 varchar , Status_Code3 varchar )
    returns varchar 
    as--to get sume of workdays in a given date range
$$
    WITH cte AS ( 
        SELECT 'can' DRKY, '1' DRSY, '2' DRRT, 'output1' DRDL01
    )
    SELECT TRIM(DRDL01) 
    FROM    cte
    WHERE TRIM(DRKY)= TRIM(Status_Code1) and TRIM(DRSY) = TRIM(Status_Code2) AND TRIM(DRRT) = TRIM(Status_Code3) 
$$
;

с реальной функцией, имеющей вид:

create or replace function Get_Status_Description(Status_Code1 varchar, Status_Code2 varchar , Status_Code3 varchar ,brand varchar) 
    returns varchar as 
$$ 
    SELECT TRIM(DRDL01) 
    FROM DB.Schema.F0005
    WHERE TRIM(DRKY)= TRIM(Status_Code1) and TRIM(DRSY) = TRIM(Status_Code2)
       AND TRIM(DRRT) = TRIM(Status_Code3) AND brand='TPH' 
$$;

1 Ответ

1 голос
/ 06 мая 2020

Сообщение об ошибке сообщает, что вы выполняете коррелированный подзапрос, который Snowflake не поддерживает. Какой SQL сервер поддерживает.

Теперь ваш вопрос был отредактирован, поэтому контекст более заметен. Я вижу, что проблема отмечена, как указано выше.

Во-первых, даже если это сработало, вы получите нет результатов, так как в вашем случае сравнение 'can' с 'Can' и в строках снежинки сравнивается с учетом регистра.

Во-вторых, CTE ваших данных может быть переписан как

WITH cte AS (
     SELECT * FROM VALUES ('CAN', 1), ('Ban', 2)  v(a, b)
)

, что позволяет добавлять больше строк проще.

Общее правило - не вызывать функции в ФИЛЬТРАХ, поэтому TRIM должны выполняться в ваших CTE:

WITH cte AS (
     SELECT TRIM(a) AS a, b FROM VALUES ('CAN', 1), ('Ban', 2)  v(a, b)
)

и

WITH cte AS ( 
    SELECT TRIM(column1) AS drky
        ,TRIM(column2) AS drsy
        ,TRIM(column3) AS drrt
        ,TRIM(column4) AS drdl01
    FROM VALUES ('can', '1', '2', 'output1');
)

и, таким образом, это будет работать, если мы проигнорируем отсутствие совпадающих данных:

WITH cte AS (
     SELECT TRIM(a) AS a, b FROM VALUES ('CAN', 1), ('Ban', 2)  v(a, b)
), Status_Descriptiontest AS ( 
    SELECT TRIM(column1) AS drky
        ,TRIM(column2) AS drsy
        ,TRIM(column3) AS drrt
        ,TRIM(column4) AS drdl01
    FROM VALUES ('can', '1', '2', 'output1')
)
SELECT sd.drdl01 as  description,
    c.*
FROM cte AS c
JOIN Status_Descriptiontest AS sd
    ON sd.DRKY = c.a and sd.DRSY = '1' AND sd.DRRT = '2';

, поэтому переходим к ILIKE, чтобы получить точное совпадение без учета регистра:

WITH cte AS (
     SELECT TRIM(a) AS a, b FROM VALUES ('CAN', 1), ('Ban', 2)  v(a, b)
), Status_Descriptiontest AS ( 
    SELECT TRIM(column1) AS drky
        ,TRIM(column2) AS drsy
        ,TRIM(column3) AS drrt
        ,TRIM(column4) AS drdl01
    FROM VALUES ('can', '1', '2', 'output1')
)
SELECT sd.drdl01 as  description,
    c.*
FROM cte AS c
JOIN Status_Descriptiontest AS sd
    ON sd.DRKY ilike c.a and sd.DRSY ilike '1' AND sd.DRRT ilike '2';

дает:

DESCRIPTION    A    B
output1        CAN  1

Фактически все, что вы хотите сделать в функции SQL, вы можете сделать в CTE, так что вы также можете сделать это.

...