Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Try catch в скалярной функции.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1194
Доброго времени суток!
Есть некая проверка на ввод параметра определенного типа в триггере. Данный параметр суть дата в строке ДД.ММ.ГГГГ, по нему идет сравнение с неким диапазоном дат.
Мне бы хотелось сделать некую свою функцию, которая или возвращала бы что заданная строка не может/может быть преобразована в дату или бы возвращала дату или null. Чтобы те строки в inserted, по которым упадет Convert(datetime, dt, 104) обрабатывать отдельно. Учитывая версию MS SQL 2008 и то, что trycast там еще нет, а в скалярке нельзя юзать "begin try", как это лучше организовать?
9 июн 17, 16:25    [20553691]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Cammomile
Member

Откуда:
Сообщений: 1212
У нас CAST/CONVERT/ISNUMERIC не генерирует ошибку в работе. Пишите функцию которая делает то что вам надо,а вот уже ее результат можете кидать в эророр, класть в логи, или еще что.
9 июн 17, 16:37    [20553726]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Cammomile
Member

Откуда:
Сообщений: 1212
https://www.sql.ru/forum/1045426/analog-try-cast-v-2008
9 июн 17, 16:39    [20553736]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36695
Cammomile
У нас CAST/CONVERT/ISNUMERIC не генерирует ошибку в работе.
У вас какая-то другая СУБД?
9 июн 17, 16:39    [20553738]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Cammomile
Member

Откуда:
Сообщений: 1212
Оуч, нет, этоя попутал. Спал 4 часа сегодня, небольшое помутнение сознания.
9 июн 17, 16:40    [20553745]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7401
denis_viktorovich,

грубо оценить можно, например, так:

if '22.12.1900' like '[0-3][0-9].[0-1][0-9].[1-2][0-9][0-9][0-9]'
	print 'ok'
else
	print 'bad';


а вообще напишите CRL функцию.
9 июн 17, 16:43    [20553755]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7401
CLR, разумеется.
9 июн 17, 16:45    [20553761]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1194
Cammomile,
Хм, как не генерирует...

select convert(datetime, '31.02.2017', 104)

мне просто хотелось бы выделить такие строчки в выборке и обработать отдельно.
Вот функция это первое, про что подумал, но как там проверить конвертируемость строки и обойти ошибку, сходу не соображу. Ну кроме тщательного программного анализа строки, с учетом месяца, високосности года и т.д.
9 июн 17, 16:49    [20553772]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Cammomile
Member

Откуда:
Сообщений: 1212
Совсем грубо можно вот так
SELECT     ISNUMERIC( REPLACE(input,'.',''))  
	FROM (
		VALUES ( '2012.05.23'      )
		,      ( 'bad date string' )
		)
		a(input)
   
9 июн 17, 16:51    [20553776]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Cammomile
Member

Откуда:
Сообщений: 1212
автор
Хм, как не генерирует...
переутомился на работе, говорю же
9 июн 17, 16:52    [20553778]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
msLex
Member

Откуда:
Сообщений: 7733
Cammomile
Совсем грубо можно вот так
SELECT     ISNUMERIC( REPLACE(input,'.',''))  
	FROM (
		VALUES ( '2012.05.23'      )
		,      ( 'bad date string' )
		)
		a(input)
   

Вам все же лучше поспать.
9 июн 17, 16:55    [20553786]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
Cammomile
Member

Откуда:
Сообщений: 1212
автор
мне просто хотелось бы выделить такие строчки в выборке и обработать отдельно.

OUTER APPLY на сложную проверяющую функциию , вот и выделение.
9 июн 17, 16:55    [20553787]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
invm
Member

Откуда: Москва
Сообщений: 9125
denis_viktorovich
как это лучше организовать?
declare @t table (dt varchar(30));

insert into @t
values
 ('20.06.2017'), ('21.6.17'), ('21.06.17'), ('aaa');

select
 t.dt, case when isdate(a.dt) = 1 then cast(a.dt as date) end
from
 @t t cross apply
 (select parsename(t.dt, 1) + parsename(t.dt, 2) + parsename(t.dt, 3)) a(dt);
9 июн 17, 17:15    [20553846]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
msLex
Member

Откуда:
Сообщений: 7733
invm
denis_viktorovich
как это лучше организовать?
declare @t table (dt varchar(30));

insert into @t
values
 ('20.06.2017'), ('21.6.17'), ('21.06.17'), ('aaa'), ('1.21.06.17');

select
 t.dt, case when isdate(a.dt) = 1 then cast(a.dt as date) end
from
 @t t cross apply
 (select parsename(t.dt, 1) + parsename(t.dt, 2) + parsename(t.dt, 3)) a(dt);


Сообщение было отредактировано: 9 июн 17, 17:55
9 июн 17, 17:19    [20553870]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
invm
Member

Откуда: Москва
Сообщений: 9125
msLex, спасибо.

Исправленный вариант
insert into @t
values
 ('20.06.2017'), ('21.6.17'), ('21.06.17'), ('aaa'), ('1.21.06.17');

select
 t.dt, case when isdate(a.dt) = 1 then cast(a.dt as date) end
from
 @t t outer apply
 (select parsename(dt, 1) + parsename(dt, 2) + parsename(dt, 3) where parsename(dt, 4) is null) a(dt);
9 июн 17, 18:23    [20554049]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
invm
Member

Откуда: Москва
Сообщений: 9125
В общем, хотел как лучше, а получилось...

Корректный вариант
declare @t table (dt varchar(30));

insert into @t
values
 ('20.06.2017'), ('21.6.17'), ('.21.06.17'), ('aaa'), ('1.21.06.17'), (null);

select
 t.dt, case when isdate(b.dt) = 1 then cast(b.dt as date) end
from
 @t t cross apply
 (select cast('<dp>' + replace(cast(cast('' as xml).query('sql:column("t.dt")') as varchar(100)), '.', '</dp><dp>') + '</dp>' as xml)) a(x) cross apply
 (select a.x.value('dp[3]', 'varchar(10)') + a.x.value('dp[2]', 'varchar(10)') + a.x.value('dp[1]', 'varchar(10)')) b(dt);
9 июн 17, 23:08    [20554552]     Ответить | Цитировать Сообщить модератору
 Re: Try catch в скалярной функции.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1194
invm,

Спасибо! Похоже то, что надо.
13 июн 17, 06:47    [20559296]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить