Поможите люди добрые!
Имеется две таблицы одна моя, а другая
неправильная находится в чужой базе данных.
Мне необходимо иметь копию той таблицы у себя в базе.
До сих пор все решалось путем полного удаления данных в моей таблице и вставкой данных из чужой.
Однако данный подход не позволяет отследить что конкретно изменилось в той таблице, а такая возможность была бы не лишней.
Т.е. необходимо провести какое-то сканирование данных в той таблице, и если данные в какой-либо записи отличаются - внести изменения по записи, не трогая остальные записи. (ну и конечно сбросить сведения об изменениях в отдельный лог что решается триггерами на моей таблице).
Все бы ничего, да есть некоторые сложности из-за "кривости" той таблицы и моей неопытности.
Но по порядку:
1. Для начала для удобства работы сбросил нужные данные чужой таблицы во временную #tblOutcomeContent (подробности здесь опускаю, ибо к задаче не относятся)
2. Далее идет проверка на наличие новых записей в чужой таблице и вставка этих записей в таблицу моей базы:
INSERT tblOutcomeContent (iOutcome, iNum, iNumSk, iElement, iPart, smCount)
Select _OC.iOutcome
, NUM
, NUMSK
, KOD
, PART
, CNT
From #tblOutcomeContent _OC
LEFT JOIN tblOutcomeContent OC
ON _OC.iOutcome = OC.iOutcome
Where OC.iOutcome is NULL
Print 'В таблицу tblOutcomeContent вставлено ' + Cast(@@ROWCOUNT as nvarchar) + ' строк'
При вставке срабатывает триггер, и вставленные записи так же попадают в лог.
3. Теперь необходимо проверить не изменялись ли какие-либо записи в чужой таблице, и при обнаружении изменений - провести эти изменения у меня. (Здесь я затупил и код не правильный! Т.к. по факту ни чего не меняет, ведь системе не понятно где менять):
UPDATE tblOutcomeContent
Set iNum = _OC.NUM, iNumsk = _OC.NUMSK, iElement = _OC.KOD, iPart = _OC.PART, smCount = _OC.CNT
From #tblOutcomeContent _OC Left Join tblOutcomeContent OC
On _OC.iOutcome = OC.iOutcome
And _OC.NUM = OC.iNum
And _OC.NUMSK = OC.iNumsk
And _OC.KOD = OC.iElement
And _OC.PART = OC.iPart
And _OC.CNT = OC.smCount
Where OC.iOutcome is Null
Print 'В таблице tblOutcomeContent изменено ' + Cast(@@ROWCOUNT as nvarchar) + ' строк'
По п. 3 пошли проблемы одна за другой пока вообще перестал понимать как мне добиться желаемого
3.1. Для начала прикинув что ключ в чужой таблице составной и состоит из полей iOutcome, KOD, PART переделал запрос на обновление
UPDATE tblOutcomeContent
Set iNum = _OC.NUM, iNumsk = _OC.NUMSK, iElement = _OC.KOD, iPart = _OC.PART, smCount = _OC.CNT
From #tblOutcomeContent _OC Join tblOutcomeContent OC
On _OC.iOutcome = OC.iOutcome And _OC.KOD = OC.iElement And _OC.PART = OC.iPart
Where _OC.NUM <> OC.iNum
Or _OC.NUMSK <> OC.iNumsk
OR _OC.CNT <> OC.smCount
Where OC.iOutcome is Null
Print 'В таблице tblOutcomeContent изменено ' + Cast(@@ROWCOUNT as nvarchar) + ' строк'
Вот тут задам вопрос № 1:
Если бы я оказался прав по поводу ключа насколько корректно решать задачу так? Может быть ее можно было решить проще? А если бы у меня таблица была с парой десятков полей это мне в условие Where надо было все эти поля загонять и сравнивать? А если в чужой таблице в поле Null - мне усложнять код добавляя функции типа Coalesce и т.п. Т.е. у меня стойкое ощущение что этот подход вроде и решает задачу - но можно (и должно) проще. А как не знаю.
Но продолжу. По дальнейшему я натурально в ступоре. Дело в том что чужая таблица вообще не имеет ключа (или ключом является тупо номер строки). Т.е. строки вообще могут повторяться (и повторяются - я проверял).
Вообще в рамках решаемых задач в моей базе данных это не мешает. Т.к. рассматриваемая таблица является перечнем материальных ценностей, типа перечня в счете-фактуре.
Ну забили например в счет-фактуру изоленту, потом через пару строк добавили ее же. Получилось две строки с изолентой, что в общем то ни на что не влияет, так как в итоге все учитывается (в общую стоимость по счету входит и стоимость первой изоленты и второй).
Но как отследить изменения вот в данном конкретном случае, когда нет ключа? Это вопрос № 2.
Вопросы касаются не одной таблицы, а целого ряда, где есть случаи и по вопросу №1 и по №2.