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

Откуда: СПб
Сообщений: 713
Добрый день!

На MSSQL10 есть хранимая процедура, в которой есть строка
Set @Sq = @Sq + 'SELECT D.ID FROM ' + RTRIM(@sqlbase) + '.dbo.Documents D WHERE D.DocType = 0 AND D.DocDate < ' + char(39) + CONVERT(varchar,SYSDATETIME(),104) + char(39)


Хранимка замечательно отрабатывает в ручном режиме, без каких-либо сообщений об ошибках. Но стоит сделать джоб с ней, сразу выдает "Преобразование типа данных varchar в тип данных datetime привело к выходу значения за пределы диапазона." Ошибка именно на этом CONVERT, без него всё ок. Но ведь я наоборот, из даты в варчар преобразую. И почему ручной запуск отрабатывает нормально? Пробовал в разных вариациях и convert и cast - не помогло. В чем моя ошибка?
16 июн 16, 10:41    [19299079]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
Настройки DATEFORMAT какие? И вообще так делать не комильфо. Передавайте значение как параметр и выполняйте через sp_executesql.
16 июн 16, 10:43    [19299092]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
DocDate у вас datetime, вот там и ругается когда сравнивает. Послушайте AlanDenton и сделайте через sp_executesql с параметрами
16 июн 16, 10:46    [19299109]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
fatherboard
Хранимка замечательно отрабатывает в ручном режиме, без каких-либо сообщений об ошибках. Но стоит сделать джоб с ней, сразу выдает "Преобразование типа данных varchar в тип данных datetime привело к выходу значения за пределы диапазона."
В ручном режиме выполняется под учеткой у которой дефолтный язык - русский. Для учетки агента дефолтный язык - не русский. Отсюда и ошибка.
Если не хотите переделывать, как советовали, на параметризованный вызов sp_executesql, замените 104 на 112.
16 июн 16, 10:53    [19299155]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
AlanDenton
И вообще так делать не комильфо. Передавайте значение как параметр и выполняйте через sp_executesql.
Имя базы он не передаст "как параметр" :-(
Хотя для даты так можно, да.

fatherboard
Ошибка именно на этом CONVERT, без него всё ок. Но ведь я наоборот, из даты в варчар преобразую. И почему ручной запуск отрабатывает нормально? Пробовал в разных вариациях и convert и cast - не помогло. В чем моя ошибка?
Вы преобразуете из даты в варчар, а сервер, когда выполняет запрос, рассматривает получившуюся строковую константу опять в дату, как же иначе ему выполнить запрос?
И при преобразовании он исходит из стандартного языка текущего пользователя, поэтому оно получается разное, и в одном случае случается ошибка, в другом всё работает.

Используйте для своего преобразования в строковую константу стиль YYYYMMDD, он универсальный, проблем не будет.

И на будущее - когда что то непонятно - отлаживайте!
Просто выводите получившуюся строку PRINT-ом, и сразу всё будет видно.
Навык отладки позволяет найти ошибку во много раз быстрее написания вопроса на форуме :-)
16 июн 16, 10:58    [19299190]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
invm, верное замечание про язык :)

fatherboard, к слову Вам пример небольшой, что строковые константы нужно в ISO формате писать (YYYYMMDD):

SET DATEFORMAT YMD

SET LANGUAGE English

DECLARE
      @d1 DATETIME = '2016/01/12'
    , @d2 DATETIME = '2016-01-12'
    , @d3 DATETIME = '12-jan-2016'
    , @d4 DATETIME = '20160112'

SELECT @d1, @d2, @d3, @d4
GO

SET LANGUAGE Deutsch

DECLARE
      @d1 DATETIME = '2016/01/12'
    , @d2 DATETIME = '2016-01-12'
    , @d3 DATETIME = '12-jan-2016'
    , @d4 DATETIME = '20160112'

SELECT @d1, @d2, @d3, @d4
GO
16 июн 16, 11:00    [19299203]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
o-o
Guest
fatherboard
И почему ручной запуск отрабатывает нормально?

потому что руками запускает логин с дефолтным языком русским,
а агент имеет логин с us_english.
буржуям выпадает error 242

К сообщению приложен файл. Размер - 41Kb
16 июн 16, 11:00    [19299207]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
fatherboard
Member

Откуда: СПб
Сообщений: 713
Всем спасибо!
Строка полностью передается в sp_executesql из-за имени базы, как сказал alexeyvg.
Буду пользоваться универсальным 112, почитал про него тут.

Конечно я всё выводил принтом, именно так и нашел этот конверт. Но выглядело в принте всё корректно. Думаю, invm прав насчет разных языков - ошибки в джобе на английском. Буду знать.

Еще раз всем спасибо!
16 июн 16, 11:06    [19299252]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
fatherboard,

автор
Строка полностью передается в sp_executesql из-за имени базы, как сказал alexeyvg.
так почему не использовать параметры???
16 июн 16, 11:09    [19299280]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
fatherboard
Строка полностью передается в sp_executesql из-за имени базы, как сказал alexeyvg.
Ваша строка заменяется на и потом легко параметризуется:
declare @p sysname = quotename(rtrim(@sqlbase)) + N'.sys.sp_executesql';
exec @p N'SELECT D.ID FROM dbo.Documents D WHERE D.DocType = 0 AND D.DocDate < cast(SYSDATETIME() as date)';
16 июн 16, 11:18    [19299347]     Ответить | Цитировать Сообщить модератору
 Re: Job, CONVERT и SYSDATETIME()  [new]
fatherboard
Member

Откуда: СПб
Сообщений: 713
invm
fatherboard
Строка полностью передается в sp_executesql из-за имени базы, как сказал alexeyvg.
Ваша строка заменяется на и потом легко параметризуется:
declare @p sysname = quotename(rtrim(@sqlbase)) + N'.sys.sp_executesql';
exec @p N'SELECT D.ID FROM dbo.Documents D WHERE D.DocType = 0 AND D.DocDate < cast(SYSDATETIME() as date)';


Круто! Спасибо.
16 июн 16, 11:23    [19299381]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить