Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
Объясняю ситуацию: есть таблица HistoryTable которая хранит историю состояния объекта. Поля : DateBegin (тип smalldatetime - дата начала срока действия состояния объекта), DateEnd (тип smalldatetime - дата окончания срока действия состояния объекта), S - int (собственно состояние объекта, неважно что оно отражает) Так вот... данная таблица истории позволяет узнать состояние объекта на заданную дату! Достаточно выполнить запрос SELECT S FROM HistoryTable WHERE @D BETWEEN DateBegin AND DateEnd где @D - заданная дата! Логически все просто, но поля типа smalldatetime хранят еще и время которое мне совершенно не нужно! Мне необходима точность действия состояния объекта до суток, а не до секунд. Соответственно когда я задаю в качестве параметра @D только дату в него еще подставляется текущее время и результаты запроса искажаются! Еще ко всему в таблицу HistoryTable так-же заносится время! Как и когда мне от этого избавится? Во время вставки данных в HistoryTable приводить все поля smalldatetime к единому времени (не дате)? или делать это во время выполнения запроса (приведенный запрос в хранимой процедуре) ... или есть другой способ? Подсказывайте! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 12:07 |
|
||
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
Может быть так: в триггере update inserted set dateBegin = cast( cast( dateBegin as int) as DateTime ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 12:24 |
|
||
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
Я тоже ковыряю аналогичные задачки. Я веду две истории. Одна по учетному времени, вторая по календарному. По учетному времени действительно нет необходимости хранить секунды, минуты и часы. Отсюда же следует, что период действия записей на учетном времени удобно задавать полями типа smalldatetime, а не datetime - это сократит размер записии увеличит скорость выборки по индексу. Откусить лишнее можно в триггере на insert/update (а можно и не откусывать, если заведомо известно, что клиентское приложение никогда не вернет дату вместе со временем). Кроме того, я пришел к выводу, что задавать начало и конец срока действия в одной записи нерационально с точки зрения конфликтности репликации. Я храню ОДНО поле для указания периода дейтсвия данной редакции на оси учетного времени - дату окончания действия редакции. Если Null, то оно равно бесконечности. Пример. Две записи имеют разные периоды окончания их действия, и это редакции одной записи справочника. Они разбивают ось учетного времени на три отрезка - ]-бесконечность, срок окончания действия первой записи] - на этом отрезке действует первая запись; ]срок окончания действия первой записи, срок окончания действия второй запис записи] - на этом отрезке действует вторая запись; ]срок окончания действия второй записи, плюс бесконечность[ - на этом отрезке не действует ни одна редакция записи. Для журнализации всех операций над записями вводится поле календарное время создания редакции записи (а с ним еще ID пользователя, создавшего редкацию, имя компьютера, с которого она создана). Это поле на клиенте вообще недоступно, но имеет значение по умолчанию Getdate(). Назначение понятно. Еще одно поле (bit) - флаг логического удаления. Любая модификация записей с помощью instead-триггеров превращается в добавление новой редакции записи. Прежние редакции не удаляются, и по ним не производится update. Актуальные записи отфильтровываются из истории с помощью VIEW. Модификация записи - это добавление новой редакции записи с более поздней календарной датой создания. Именно по календарной дате создания определяется актуальность записи. Удаление записи приводит к моявлению новой редакции записи с установленным флагом логического удаления. При настроке Merge-репликации конфликты отсутствуют как класс. В то же время в самой таблице лежит журнал модификации, в котором можно подглядеть, что и когда шевелил (плюс к тому еще и на каком из удаленных узлов корпоративной сети). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 12:34 |
|
||
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
To maximf: 1 нельзя апдейтить таблицы inserted и deleted! Но... ты очень помог! данная конструкция (dateBegin = cast( cast( dateBegin as int) as DateTime ) действительно обрубает время! А это мне и надо было! Поклон великий! To Garya: Да... возможны конфликты при репликации! Согласен! Но... 1 - у меня это история редкоизменяющихся параметров объекта! И я не очень уверен что и ваша организация истории оптимальна! Я всетаки настаиваю на своей! ) потому как помучался в свое время с такой как у вас. не думаю что эллементарный запрос на выборку значения на заданную дату будет очень простым! Давайте обсудим! ) мне это интересно... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 13:03 |
|
||
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
2 maximf create table #d(dateBegin datetime) insert #d select '20010101 10:00' insert #d select '20010101 20:00' update #d set dateBegin = cast( cast( dateBegin as int) as DateTime ) select * from #d Вообщем не надо такое предлагать. Можно написать так: update #d set dateBegin = cast( cast( dateBegin-0.5 as int) as DateTime ) Но тоже как-то нехорошо выглядит ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 13:05 |
|
||
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
Можно еще так update YourTable set dateBegin = convert(datetime, convert(char(, OperationStop, 1)) Не пробовал но може пройти и так: update YourTable set dateBegin = convert(char(, OperationStop, 1) Третий параметр (единица) указывает на формат даты, какие они бывают см в BOL Cast and Convert, можно такой апдейтик засунуть и в триггер, а можно и самому так писать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 13:26 |
|
||
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
Там где рожица выскочила нужно ставить восмерку со скобкой ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 13:27 |
|
||
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
Да я-то не настаиваю... Не нравится - не используй. Это просто в порядке обмена опытом. Могу привести пример запроса, если интересно. Расписывать струтктуру всех участвующих в запросах таблиц слишком долго, но по названиям многое можно понять. Если есть желание позаниматься кодокопательством, то привожу ниже тексты реально работающих запросов. Запрос, возвращающий последние на оси календарного времени модификации записи справочника единиц измерений (в том числе помеченные как логически удаленные): CREATE VIEW dbo.vwsprEdIzm_LastsAll with VIEW_METADATA AS SELECT MZ.RecID, MZ.Name, MZ.EnableBeforeAccountDate, MZ.Deleted, MZ.PeriodID, MZ.SprID, MZ.UserID, MZ.CalendCreationTime, MZ.FromStation FROM dbo.sprEdIzm MZ INNER JOIN (SELECT PeriodID, SprID, MAX(CalendCreationTime) AS LastCalendCreationTime FROM dbo.sprEdIzm GROUP BY SprID, PeriodID) SubZ ON MZ.PeriodID = SubZ.PeriodID AND MZ.SprID = SubZ.SprID AND MZ.CalendCreationTime = SubZ.LastCalendCreationTime CROSS JOIN dbo.mt_X_UsersAndSpravs X WHERE (X.UserID = dbo.CurrentUserID()) AND (X.SpravID = '{FE57C16C-E845-4BBD-874E-94975C257FE7}') AND (X.CalcPermRead = 1) Запрос, возвращающий актуальные на заданную учетную дату записи либо вместе с логически удаленными, либо без них. На какую учетную дату, а также с удаленными или без них, указывается в таблице mt_X_UsersAndSpravs1: CREATE VIEW dbo.vwsprEdIzm_MainView with VIEW_METADATA AS SELECT A1.RecID, A1.PeriodID, A1.SprID, A1.Name, A1.EnableBeforeAccountDate, A1.CalendCreationTime, A1.Deleted FROM dbo.vwsprEdIzm_LastsAll A1,(SELECT A.SprID, MIN(A.EnableBeforeAccountDate) AS BeforeDate FROM vwsprEdIzm_LastsAll A, mt_X_UsersAndSpravs1 X1, mtUserSingleParameters P WHERE X1.UserID = P.UserID AND P.UserID = dbo.CurrentUserID() AND X1.SpravID = 'FE57C16C-E845-4BBD-874E-94975C257FE7' AND (A.Deleted = X1.ShowDeleted OR X1.ShowDeleted IS NULL) AND (A.EnableBeforeAccountDate >= P.AccountCurrentPoint OR A.EnableBeforeAccountDate IS NULL) GROUP BY A.SprID) B1 WHERE A1.SprID = B1.SprID AND ISNULL(A1.EnableBeforeAccountDate, CONVERT(datetime, '05 may 2000 13:13:13', 113)) = ISNULL(B1.BeforeDate, CONVERT(datetime, '05 may 2000 13:13:13', 113)) Запрос, возвращающий для одной записи справочника, все действующие редакции записи на разных периодах учетного времени (через этот же VIEW производится добавление новых редакций для новых отрезков учетного времени): CREATE VIEW dbo.vwsprEdIzm_ViewByPeriods with VIEW_METADATA AS SELECT A.RecID, A.PeriodID, A.SprID, A.Name, A.EnableBeforeAccountDate, A.CalendCreationTime, A.Deleted FROM dbo.vwsprEdIzm_LastsAll A INNER JOIN dbo.mt_X_UsersAndSpravs1 X1 ON A.SprID = X1.CurrentSprID INNER JOIN dbo.mt_X_UsersAndSpravs X ON X.UserID = X1.UserID AND X.SpravID = X1.SpravID WHERE (X1.UserID = dbo.CurrentUserID()) AND (X1.SpravID = 'FE57C16C-E845-4BBD-874E-94975C257FE7') AND (X1.ShowDeleted = A.Deleted OR X1.ShowDeleted IS NULL) AND (X.CalcPermShowMultiPeriods = 1) Запрос, который для одной выбранной на оси учетного времени редакции записи возвращает историю ее модификации (журнал всех действий над записью) на оси календарного времени: CREATE VIEW dbo.vwsprEdIzm_ViewPeriodHistory AS SELECT TOP 100 PERCENT A.RecID, A.PeriodID, A.SprID, A.Name, U.UserOrRoleName, N.RemoteNodeName, A.CalendCreationTime, A.FromStation, A.EnableBeforeAccountDate, A.Deleted FROM dbo.mtRemoteNodes N INNER JOIN dbo.mtUsersAndRoles U ON N.RemoteNodeID = U.RemoteNodeID INNER JOIN dbo.sprEdIzm A INNER JOIN dbo.mt_X_UsersAndSpravs1 X1 ON A.SprID = X1.CurrentSprID AND A.PeriodID = X1.CurrentPeriodID ON U.UserOrRoleID = A.UserID INNER JOIN dbo.mt_X_UsersAndSpravs X ON X.UserID = X1.UserID AND X.SpravID = X1.SpravID WHERE (X1.UserID = dbo.CurrentUserID()) AND (X1.SpravID = 'FE57C16C-E845-4BBD-874E-94975C257FE7') AND (X1.ShowDeleted = A.Deleted OR X1.ShowDeleted IS NULL) AND (X.CalcPermShowHistory = 1) ORDER BY A.CalendCreationTime ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 13:38 |
|
||
|
Типы данных datetime
|
|||
|---|---|---|---|
|
#18+
SELECT CAST(CONVERT(char( 8 ),DateBegin,112) AS int) Тот же int, только гораздо наглядней. EXEC sp_addtype 'NDate', 'int', 'null' GO + соответствующий Bind Да, у нас, например, бывает нужно впихнуть в него 13-й,... (далее везде) месяц. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2001, 22:11 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32008720&tid=1826312]: |
0ms |
get settings: |
9ms |
get forum list: |
17ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
47ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
61ms |
get tp. blocked users: |
2ms |
| others: | 219ms |
| total: | 377ms |

| 0 / 0 |
