powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Передача переменной в inline UDF с CTE вызывает ошибку
8 сообщений из 8, страница 1 из 1
Передача переменной в inline UDF с CTE вызывает ошибку
    #39694240
tunknown
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sql 12.0.5000.0 (X64) + 12.0.5557.0 (X64)
Кажется, что-то подобное уже исправляли в 2012.
Наткнулся случайно, если бы данные были чуть другими, то ошибку не заметил бы и она всплыла бы на боевом сервере.
Чего нужно избегать в таких случаях? Излишние проверки добавлены с целью обойти ошибку, но они не помогли.
Такое впечатление, что оптимизатор развернул запрос настолько, что текстовые функции стали выполняться раньше условий.
Ошибка возникает и при передаче переменной и при передаче поля. С константой ошибки нет, видимо, из-за того, что план другой получается.
Как лучше парсить email меня не интересует.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
use	tempdb
go
create	function	dbo.GetEmailDomainDS
(	@sEmail	varchar ( 512 ) )
returns	table
as
return	( with	cte	as
	(	select
			Value=	null
		where
			@sEmail	not	like	'%_@_%._%'
		union	all
		select
			Value=	substring ( @sEmail,	charindex ( '<',	@sEmail )+	1,	charindex ( '>',	@sEmail )-	charindex ( '<',	@sEmail )-	1 )
		where
				@sEmail		like	'%<%_@_%._%>%'
			and	charindex ( '<',	@sEmail )<	charindex ( '>',	@sEmail )
		union	all
		select
			Value=	@sEmail
		where
				@sEmail		like	'%_@_%._%'
			and	@sEmail	not	like	'%<%_@_%._%>%' )
	select
		Value=	right ( Value,	len ( Value )-	charindex ( '@',	Value ) )
	from
		cte
	where
			Value	like	'%_@_%'
		and	charindex ( '@',	Value )<	len ( Value ) )
go
select	*	from	dbo.GetEmailDomainDS ( 'Ivan Ivanov <ii@domain.ru>;' )


Код: sql
1.
2.
3.
declare @s varchar(512)='qr@qr.qr'
select 1,* from tempdb.dbo.GetEmailDomainDS ( 'qr@qr.qr' ) -- работает
select 2,* from tempdb.dbo.GetEmailDomainDS ( @s ) -- ошибка
...
Рейтинг: 0 / 0
Передача переменной в inline UDF с CTE вызывает ошибку
    #39694251
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tunknown, используй case
...
Рейтинг: 0 / 0
Передача переменной в inline UDF с CTE вызывает ошибку
    #39694253
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
create	function	dbo.GetEmailDomainDS
(	@sEmail	varchar ( 512 ) )
returns	table
as
return	( with	cte	as
	(	select
			Value=	null
		where
			@sEmail	not	like	'%_@_%._%'
		union	all
		select
		 Value = substring ( @sEmail, t.a + 1, t.b - t.a - 1 )
		from
		 (select nullif(charindex ( '<',	@sEmail ), 0), nullif(charindex ( '>',	@sEmail ), 0)) t(a, b)
		where
		 @sEmail		like	'%<%_@_%._%>%'
		 and	t.a < t.b
		union	all
		select
			Value=	@sEmail
		where
				@sEmail		like	'%_@_%._%'
			and	@sEmail	not	like	'%<%_@_%._%>%' )
	select
		Value=	right ( Value,	len ( Value )-	charindex ( '@',	Value ) )
	from
		cte
	where
			Value	like	'%_@_%'
		and	charindex ( '@',	Value )<	len ( Value ) )
go
...
Рейтинг: 0 / 0
Передача переменной в inline UDF с CTE вызывает ошибку
    #39694260
tunknown
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
busertunknown, используй caseНедосмотрел. Спасибо, case сработал в моём простом случае.

Однако, вопрос остаётся. Как избегать этого, если нужно CTE?
...
Рейтинг: 0 / 0
Передача переменной в inline UDF с CTE вызывает ошибку
    #39694265
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tunknownС константой ошибки нет, видимо, из-за того, что план другой получается.
Да, с константой сервер пропускает некоторые из union all
Вам нужно поправить ошибку во втором из них:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
declare @sEmail varchar(512)='qr@qr.qr'
;with	cte	as
(	
	select
		Value=	substring ( @sEmail,	charindex ( '<',	@sEmail )+	1,	charindex ( '>',	@sEmail )-	charindex ( '<',	@sEmail )-	1 )
	where
			@sEmail		like	'%<%_@_%._%>%'
		and	charindex ( '<',	@sEmail )<	charindex ( '>',	@sEmail )
)
select
	Value=	right ( Value,	len ( Value )-	charindex ( '@',	Value ) )
from
	cte
where
		Value	like	'%_@_%'
	and	charindex ( '@',	Value )<	len ( Value )
...
Рейтинг: 0 / 0
Передача переменной в inline UDF с CTE вызывает ошибку
    #39694266
tunknown
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

Так тоже работает. Спасибо.
...
Рейтинг: 0 / 0
Передача переменной в inline UDF с CTE вызывает ошибку
    #39694267
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tunknownОднако, вопрос остаётся. Как избегать этого, если нужно CTE?Хм, при чём тут CTE???
У вас просто ошибка в запросе (достаточно типичная). Вы думаете, что выражение в SELECT не выполняется для тех строк, которые не попадают под условие. А оно может выполняться для любых строк.
...
Рейтинг: 0 / 0
Передача переменной в inline UDF с CTE вызывает ошибку
    #39694281
tunknown
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgВы думаете, что выражение в SELECT не выполняется для тех строк, которые не попадают под условие. А оно может выполняться для любых строк.Да, моя ошибка. Оптимизатор слишком умён стал, о чём и задокументировано.
BOL Select Logical Processing Order of the SELECT statement
Note that the actual physical execution of the statement is determined by the query processor and the order may vary from this list.

FROM

ON

JOIN

WHERE

GROUP BY

WITH CUBE or WITH ROLLUP

HAVING

SELECT

DISTINCT

ORDER BY

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


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