powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Рекурсивный запрос (CTE) выдает ошибку в 2019
12 сообщений из 12, страница 1 из 1
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989306
urachins
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть sql-функция GetPhaseID, которая использует CTE запрос типа
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
with parent_list as 
	(
	   select ...  from erp.ProjPhase mt 
	   union all
	   select mt.PhaseID,  chl.myLevel + 1 as myLevel, mt.ParentPhase, mt.RecognizeRevenueAtChildPhaseLevel
	   from erp.ProjPhase mt 
	   inner join parent_list chl on ... 
)



Следующий запрос стал выдавать ошибку на 2019 сервере:
Код: sql
1.
2.
3.
4.
5.
---> System.Data.SqlClient.SqlException: Invalid object name 'parent_list'.

select .... from erp.ProjPhase as a  inner join erp.jobhead as b
		 on a.erp_ProjPhase.company = b.company and b.projectid = erp_jobhead.projectid 
		 and a.phaseid = erp.[GetPhaseID](b.company, b.projectid, b.phaseid)



На 2017 сервере все было нормально. В чем причина?

Спасибо
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989308
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ошибка, видимо, в 18й строке функции erp.[GetPhaseID]
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989318
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
urachins,

Это не ошибка SQL. Это ошибка .NET внутри CLR.

Может быть вызвана тем, что какие библиотеки недоставлены.
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989320
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, да, в SSMS запрос выполняется?
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989322
urachins
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, у меня выполняется без ошибки, у клиента - ошибка
нашел что-то похожее, рекомендуют просто перекомпилировать эту функцию:

https://dba.stackexchange.com/questions/256861/after-sql-restart-cte-causes-invalid-object-name-error-for-a-short-period-in-sq
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989432
urachins
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Смог воспроизвести у себя на 2019 только когда меняю совместимость базы на 150 как у клиента (для 140 все нормально)
Это бага MS Sql?

ALTER DATABASE MYTest SET COMPATIBILITY_LEVEL = 150

select * from erp.ProjPhase as a where erp.[ GetPhaseID ](a.company, a.projectid, a.phaseid) <> '1'

Msg 208, Level 16, State 1, Procedure GetPhaseID, Line 36 [Batch Start Line 12]
Invalid object name 'parent_list'.
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989433
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или делайте, чтобы работало (там накидали по ссылке воркэраундов), или отключайте инлайнинг без понижения compatibility_level:

ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = OFF;

Подробности, как всегда, в документации .
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989505
urachins
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, по документации, действительно говорится, что во встроенный функциях CTE использовать нельзя

The UDF does not contain references to Common Table Expressions (CTEs).

Проблема в том, что по умолчанию при переходе на 2019 параметр базы будет TSQL_SCALAR_UDF_INLINING = ON то есть все функции будут рассматриваться как встраиваемые. Отключать его не хочется.
Последние два вопроса

1) Можно проверить каждую существующую функцию, удовлетворяет ли она условиям на встраиваемость и если нет то в скриптах на их создание добавить хинт WITH INLINE = OFF , но этот хинт не поддерживается в ранних версиях.
Можно ли сделать универсальный скрипт для любой версии ?

2) Почему после перекомпиляции функции в 2019 сервер уже не ругается? Хотя рекурсивные CTE там остались.

Спасибо
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989555
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
urachins,

просто старайтесь не использовать скалярные функции в запросах.
Рекурсивный запрос для дерева можно заменить например, на использование иерархического типа.

Также создайте проект базы в VS, напишите тесты, выполняйте развертывание и тестирование. Сразу исчезнут многие неожиданности. Хотя это может быть и трудоёмко, если разработка не велась так с самого начала. Используйте системы версионирования кода.
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989789
urachins
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, согласен, спасибо, хотя в этом направлении мне пока не все понятно и многому надо учиться. Рекурсивный CTE использовал для простого обхода дерева снизу до корня, для подобных целей его, наверное, и придумали.

По основному вопросу оказалось, что при переходе на (2019) с (2017) через простое восстановление базы sql для каждой функции сам выставляет новые параметры inline_type, is_inlineable, указывающие, может ли она быть встроенной или нет:

SELECT inline_type, is_inlineable FROM sys.sql_modules where OBJECT_NAME(object_id) = 'GetPhaseID'

Для большинства функций делает это правильно, типа, для простых - 1, для сложных - 0. Но именно для функций, использующих CTE он ошибается и ставит 1 (встраиваемая) и тогда при использовании ее в запросе вылезает ошибка.
Если же функцию перекомпилировать, то sql правильно ее распознает и ставит в эти поля 0.
Более того, в такой функции он не дает в скрипте на создание поставить хинт WITH INLINE = ON

Пока вижу один вокэраунд - при переходе на 2019 заставлять запустить скрипты на пересоздание функций.

Как-то можно это автоматизировать? клиентов много и каждый сам решает в какой момент перейти на 2019.
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989794
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
urachins,

непростая задача, если вы поставщик ПО, то должны разработать способ обновления версий базы. Если она у вас вообще версионирована. Например, соберите два варианта скрипта обновления для очередного обновления, каждый из которых будет выполнен в зависимости от версии сервера, не который устанавливается.
...
Рейтинг: 0 / 0
Рекурсивный запрос (CTE) выдает ошибку в 2019
    #39989897
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
urachins
Да, согласен, спасибо, хотя в этом направлении мне пока не все понятно и многому надо учиться. Рекурсивный CTE использовал для простого обхода дерева снизу до корня, для подобных целей его, наверное, и придумали.

По основному вопросу оказалось, что при переходе на (2019) с (2017) через простое восстановление базы sql для каждой функции сам выставляет новые параметры inline_type, is_inlineable, указывающие, может ли она быть встроенной или нет:

SELECT inline_type, is_inlineable FROM sys.sql_modules where OBJECT_NAME(object_id) = 'GetPhaseID'

Для большинства функций делает это правильно, типа, для простых - 1, для сложных - 0. Но именно для функций, использующих CTE он ошибается и ставит 1 (встраиваемая) и тогда при использовании ее в запросе вылезает ошибка.
Если же функцию перекомпилировать, то sql правильно ее распознает и ставит в эти поля 0.
Более того, в такой функции он не дает в скрипте на создание поставить хинт WITH INLINE = ON

Пока вижу один вокэраунд - при переходе на 2019 заставлять запустить скрипты на пересоздание функций.

Как-то можно это автоматизировать? клиентов много и каждый сам решает в какой момент перейти на 2019.
документ разослать
при переходе на скл-2019 обратитесь в службу поддержки

да и вообще
сама идея смены версии без согласования с поддержкой выглядит странновато
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Рекурсивный запрос (CTE) выдает ошибку в 2019
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]