#sql #sql-server #sql-server-2005
#sql #sql-сервер #sql-server-2005
Вопрос:
Может кто-нибудь, пожалуйста, помочь мне с sql.
У меня есть таблица с полями:
ИДЕНТИФИКАТОР (guid), DocumentNumber (varchar), RefDocumentNumber (varchar), DocumentDate (datetime).
Документы сопряжены, что означает:
(исходный документ)
- Идентификатор: 1111-111…
- Номер документа: 1
- RefDocumentNumber: пустая строка
- Дата: 2014-06-25 12:11:24.890
(документ, на который ссылаются)
- Идентификатор: 2222-2222
- Номер документа: 2
- RefDocumentNumber: 1
- Дата: 2014-06-25 12:12:24.890
Проблема в том, что у меня есть некоторые ситуации, когда справочный документ имеет «более молодую дату». Поэтому мне нужно обновить его дату с помощью функции DATEADD (добавить 60 секунд).
Это произошло из-за сбоя во времени сервера…
Может кто-нибудь, пожалуйста, помочь мне с:
- Поиск этих записей (я хочу знать, сколько ссылочных документов необходимо обновить)
- Помогите мне с «безопасным» обновлением этих документов, на которые ссылаются (на самом деле цикл ОБНОВЛЕНИЯ MyTable УСТАНАВЛИВАЕТ documentdate= DATEADD (ss, 60, documentdate), где documentnumber = ‘1’
Спасибо.
Ответ №1:
Что-то вроде этого:
UPDATE OD SET OD.Date = RD.Date
FROM Dokument OD
JOIN Dokument RD ON OD.DocumentNumber = RD.RefDocumentNumber
WHERE OD.Date < RD.Date
или:
UPDATE OD SET OD.Date = DATEADD(second,-120,OD.Date)
FROM Dokument OD
JOIN Dokument RD ON OD.DocumentNumber = RD.RefDocumentNumber
WHERE OD.Date < RD.Date
только выбранный штамент:
Select DISTINCT OD.Id
FROM Dokument OD
JOIN Dokument RD ON OD.DocumentNumber = RD.RefDocumentNumber
WHERE OD.Date < RD.Date
Комментарии:
1. Первое обновление устанавливает дочернюю дату такой же, как родительская дата, не старше. Кроме того, добавление 60 секунд к дате делает ее моложе, а не старше.
2. Отредактировано. В любом случае, если ссылочная запись должна быть копией исходного документа, поэтому первое обновление было бы лучшим подходом
Ответ №2:
Вы можете использовать курсор для перебора всех записей:
DECLARE curYoungRecords CURSOR FOR
SELECT a.Id, a.DocumentDate
FROM Documents a
INNER JOIN Documents b ON b.DocumentNumber = a.RefDocumentNumber
AND b.DocumentDate < a.DocumentDate
DECLARE @DocId UNIQUEIDENTIFIER
DECLARE @DocDate DATETIME
OPEN curYoungRecords
FETCH NEXT FROM curYoungRecords INTO @DocId, @DocDate
WHILE @@FETCH_STATUS = 0
BEGIN
-- Make record "older" by 120 seconds
UPDATE Documents
SET DocumentDate = DATEADD(second, -120, @DocDate)
WHERE Id = @DocId
FETCH NEXT FROM curYoungRecords INTO @DocId, @DocDate
END
CLOSE curYoungRecords
DEALLOCATE curYoungRecords
INNER JOIN
Гарантирует, что включены только «дочерние» документы, в которых дата документа моложе родительской.
Комментарии:
1. Обратите внимание, что инструкция update установит для «дочерних» документов ту же дату и время, что и для родительских; это предполагаемый результат или он должен быть старше?
2. цель состоит в том, чтобы убедиться, что родительский документ имеет более старую дату, чем ссылочный (дочерний) документ. В настоящее время из-за неправильного времени сервера дочерние документы выглядят так, как будто они были созданы раньше родительских…
3. Учитывая, что пример данных в вопросе составляет 60 секунд между родительским и дочерним, я изменил
UPDATE
на 120 секунд.