NAV+SQL: Как мы победили (часть 2)

Эта статья — продолжение темы, начатой в «NAV+SQL: подружки-хохотушки».

Следующим шагом было написать функции, которые будут приводить сиквельные дату и время к навижнновскому стандарту.
В Navision пустая дата (0D) — это на самом деле 1 января 1753 года. А пустое время (0T) — 1 января 1754 года.
Соответственно, непустое время — это 01.01.1754 ЧЧ:ММ:СС.

Функции для получения даты/времени в навижновском формате на T-SQL:

CREATE FUNCTION dbo.UDF_Navision_Date(@DATE datetime)
RETURNS datetime
AS
BEGIN
  RETURN ( CAST(str(YEAR(@DATE)) + '-' + str(MONTH(@DATE)) + '-' + str(DAY(@DATE))  AS datetime))
END
CREATE FUNCTION dbo.UDF_Navision_Time(@DATE datetime)
RETURNS datetime
AS
BEGIN
RETURN ( CAST( '1754-01-01 '
   + STR(DATEPART(hh, @DATE)) + ':'
   + STR(DATEPART(mi, @DATE)) + ':'
   + STR(DATEPART(ss, @DATE))  AS datetime))
END
CREATE FUNCTION [dbo].[UDF_Date_Time](@DATE datetime, @TIME datetime)
RETURNS datetime
AS
BEGIN
  RETURN (
    CAST(str(YEAR(@DATE)) + '-' + str(MONTH(@DATE))  + '-' + str(DAY(@DATE)) + ' ' +
    str(DATEPART(HOUR,@TIME))  + ':' + str(DATEPART(MINUTE,@TIME)) + ':' + str(DATEPART(SECOND,@TIME))
  AS datetime))
END

Перевертыши – функции в NAV, из которых получаются дата/время в формате SQL (yyyymmdd hh:mm:ss):

// Возвращает дату в формате YYYYMMDD
PROCEDURE GetSQLDate(dateInput : Date) : Text[30];
BEGIN
  EXIT(FORMAT(dateInput,0, '<Year4><Month,2><Day,2>'));
END;
// Возвращает время, которое можно записать на сервер
PROCEDURE GetSQLTime(timeInput : Time) : Text[30];
BEGIN
  EXIT(FORMAT(timeInput,0, '1754-01-01 <Hours24>:<Minutes>:<Seconds>'));
END;

Аналог USERID для SQL Server:

CREATE FUNCTION dbo.UDF_User_Name()
RETURNS nvarchar(100)

BEGIN

  DECLARE @USER nvarchar(100)

  SET @USER = suser_sname()
  RETURN (SELECT UPPER(SUBSTRING(@USER, patindex('%\%', @USER)+1, LEN(@USER))))

END

Очередной нюанс работы с сиквелом касается типа данных DateTime. На первый взгляд — точная копия сиквеловского datetime, Но –  одно важное НО: в базе навижновское поле хранится в формате UTC (бывший GMT – Greenwich Mean Time). Если не знать этого факта (я до определенного времени не знал :) — то можно сильно удивиться, сделав в Query Analizer’е SELECT из таблички с этим полем, сравнить время и увидеть — оно отстает на 3 часа (для Москвы).

Вывод – при работе с полями DateTime вместо функции GETDATE() надо использовать GETUTCDATE().
Вывод номер два – при построении сложных распределенных систем надо учитывать фактор смены часовых поясов – и – о чудо! – тут нам тоже придет на помощь тип данных DateTime :)

Хочу заметить, что для отдельных типов Date и Time это правило не работает (логично). Более того, функции TODAY() и TIME() возвращают значения, установленные в операционной системе.

Так, потихоньку, инструментарий стал пополняться, и от рутины можно было переходить к творчеству :-)

Продолжение читайте здесь

Автор:

В области Navision - с 2003 года. Профессиональные интересы: NAV, MS SQL, .NET, BPMN, IT-менеджмент. Предметная область: логистика, финансы, склады, 3PL.

Количество статей, опубликованных автором: 86.

Добавить комментарий