Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Синхронизация таблиц (число прочтений - 5886 )
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Синхронизация таблиц
09. Апреля 2008 :: 09:36
Печать  
Ничего умнее для названия не придумал, на самом деле возможно все не так сложно. Имеем две таблицы А и Б, структура почти идентичная (для простоты: Таблица А - одно поле ID, Таблица Б - два поля: ID и New). Задача: ПЕРЕНЕСТИ записи из таблицы А в таблицу Б. Правило: Если ID есть, то просто (UPDATE) признак New =1, если записи нет, то добавить (INSERT) и new = 1.
Если честно, то даже не представляю как такое сделать.
К примеру: Талица Б
100001 0
100002 0
100003 0
Таблица А
100003
100004
После "синхронизации" Таблица А - пустая, таблица Б:
100001 0
100002 0
100003 1
100004 1
В принципе, можно в таблицу А добавить поле new и заполнять его единицей, это не критично. Но не ясен сам процесс такого обновления если есть или нет.
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Синхронизация таблиц
Ответ #1 - 09. Апреля 2008 :: 10:01
Печать  
Update Б
Set New = 1
Where
 ID IN (Select ID From А)

Insert Into Б
(ID, NEW)
Select
 ID, 1
From А
Where
 ID NOT IN (Select ID From Б)

Delete From A
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #2 - 09. Апреля 2008 :: 10:09
Печать  
О! Спасибо... Как говориться умом понимаю, математически выразить не могу (с) Анекдот...
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #3 - 09. Апреля 2008 :: 10:39
Печать  
Тэкс... А если усложнить? С одним обновляемым полем я понял, а как обновить остальные поля (к примеру DESCR), замещая данные из таблицы А?. Допустим:
Таблица Б
100001 "мама" 0
100002 "мыла" 0
100003 "раму" 0
Таблица А
100002 "рыла"
100003 "глубокую"
100004 "канаву"
После "синхронизации" Таблица А - пустая, таблица Б:
100001 "мама" 0
100002 "рыла" 1
100003 "глубокую" 1
100004 "канаву" 1
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Синхронизация таблиц
Ответ #4 - 09. Апреля 2008 :: 10:46
Печать  
zenik писал(а) 09. Апреля 2008 :: 10:39:
...а как обновить остальные поля (к примеру DESCR), замещая данные из таблицы А?. 


Update Б
Set
  Колонка1 = <Значение>,
  Колонка2 = <Значение>,
  ...
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #5 - 09. Апреля 2008 :: 11:52
Печать  
т.е. должно выглядеть как то так или можно проще?

     |UPDATE ArticleGroup
     |      SET
     |            NEW = 1,

     |          DESCR = (SELECT DESCR FROM ArticleGroup1S WHERE ID IN (SELECT ID FROM ArticleGroup1S))
Вот эта строка меня очень сильно смущает... Слишком громоздко...
     |WHERE
     |      ID IN (SELECT ID FROM ArticleGroup1S)
     |INSERT INTO ArticleGroup
     |      (ID,ParentID,Level,Descr,isDel,New)
     |SELECT ID,ParentID,Level,Descr,isDel,1
     |FROM ArticleGroup1S
     |WHERE ID NOT IN (SELECT ID FROM ArticleGroup)
     |DELETE FROM ArticleGroup1S
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Синхронизация таблиц
Ответ #6 - 09. Апреля 2008 :: 12:06
Печать  
Если все-таки заглянуть в BOL, то сможем увидеть так вот такой пример:

Код
Выбрать все
UPDATE titles
   SET ytd_sales = titles.ytd_sales + sales.qty
	FROM titles, sales
	   WHERE titles.title_id = sales.title_id
	   AND sales.ord_date = (SELECT MAX(sales.ord_date) FROM sales)


 

  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #7 - 09. Апреля 2008 :: 12:43
Печать  
Спасиб. Работает. Но все же хотелось бы узнать правильно или нет?

UPDATE ArticleGroup
SET
     NEW            = 1
     ,ParentID      =ArticleGroup1S.ParentID
     ,Level            =ArticleGroup1S.Level
     ,Descr            =ArticleGroup1S.Descr
     ,isDel            =ArticleGroup1S.isDel
FROM ArticleGroup,ArticleGroup1S WHERE ArticleGroup.ID IN (SELECT ID FROM ArticleGroup1S)
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Синхронизация таблиц
Ответ #8 - 09. Апреля 2008 :: 13:15
Печать  
Правильно. Единственно, я бы

FROM ArticleGroup,ArticleGroup1S

переписал на человеческое связывание...
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #9 - 09. Апреля 2008 :: 13:39
Печать  
Оно?
UPDATE ArticleGroup
SET
     NEW            = 1
     ,ParentID      =Source.ParentID
     ,Level            =Source.Level
     ,Descr            =Source.Descr
     ,isDel            =Source.isDel
FROM ArticleGroup AS Dest
INNER JOIN
     ArticleGroup1S AS Source ON Source.ID=Dest.ID
     AND Dest.ID IN (SELECT ID FROM ArticleGroup1S)
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Синхронизация таблиц
Ответ #10 - 09. Апреля 2008 :: 13:54
Печать  
Почти Улыбка

UPDATE ArticleGroup 
SET 
     NEW            = 1
     ,ParentID      =Source.ParentID
     ,Level            =Source.Level
     ,Descr            =Source.Descr
     ,isDel            =Source.isDel
FROM ArticleGroup AS Dest (NoLock)
LEFT JOIN
     ArticleGroup1S AS Source (NoLock) ON Source.ID=Dest.ID 
WHERE
     Dest.ID IN (SELECT ID FROM ArticleGroup1S (NoLock))
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #11 - 09. Апреля 2008 :: 14:25
Печать  
noLock там врядли понадобится. Этими таблицами будет пользоваться только эта обработка... Можно сказать будет монопольно трудиться, так что нет смысла.

Еще раз спасибо.

p.s. По поводу LEFT тоже не актуально, ID то уникальный... (или я не прав?)
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Синхронизация таблиц
Ответ #12 - 10. Апреля 2008 :: 03:51
Печать  
zenik писал(а) 09. Апреля 2008 :: 14:25:
noLock там врядли понадобится. Этими таблицами будет пользоваться только эта обработка... Можно сказать будет монопольно трудиться, так что нет смысла.


Тогда тем более стоит поставить NoLock. Чтобы скуль не тратил ресурсов на блокирование таблиц.

zenik писал(а) 09. Апреля 2008 :: 14:25:
p.s. По поводу LEFT тоже не актуально, ID то уникальный... (или я не прав?)


Просто, с LEFT JOIN скуль чаще всего строит более кроасивый план запроса , чем с INNER JOIN.
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #13 - 10. Апреля 2008 :: 04:53
Печать  
Учту. Спасибо.
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #14 - 08. Апреля 2009 :: 10:32
Печать  
О как время быстро летит... Уже год прошел  Класс.

Подскажите еще плз. Как усовершенствовать запрос и сделать условие по 2-м ключам - ID и ParentID?
  
Наверх
 
IP записан
 
kriblya
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 313
Зарегистрирован: 24. Декабря 2007
Re: Синхронизация таблиц
Ответ #15 - 08. Апреля 2009 :: 12:01
Печать  

INSERT INTO Б VALUES (список колонок)
ON DUPLICATE KEY UPDATE new=0,...
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #16 - 08. Апреля 2009 :: 13:02
Печать  
Это мы в курсе... Мне бы для MSSQL такой ход.
  
Наверх
 
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Синхронизация таблиц
Ответ #17 - 08. Апреля 2009 :: 15:58
Печать  
Условие где?

Можно тупенько

Dest.ID+Dest.ParentID IN (SELECT ID+ParentID FROM ArticleGroup1S (NoLock))
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #18 - 09. Апреля 2009 :: 06:21
Печать  
Решил задачу вот так. Посмотрите, все ли правильно, может чего не хвататет, а может что и лишнее:

Код
Выбрать все
DECLARE
  @ID			numeric(5),
  @ArticleID	numeric(6),
  @Barcode		varchar(30),
  @Size			numeric(15,3),
  @isDel		bit

DECLARE i_Barcode_cursor INSENSITIVE CURSOR
  FOR SELECT * FROM i_Barcode
OPEN i_Barcode_cursor
FETCH NEXT FROM i_Barcode_cursor
  INTO @ID,@ArticleID,@Barcode,@Size,@isDel
WHILE @@FETCH_STATUS = 0
BEGIN
  IF EXISTS (SELECT * FROM Barcode WHERE ID = @ID AND ArticleID = @ArticleID)
    UPDATE Barcode SET Barcode = @Barcode, Size = @Size, isDel = @isDel, isNew = 1, isUpdate = 0 WHERE ID = @ID AND ArticleID = @ArticleID
  ELSE
    INSERT Barcode VALUES (@ID,@ArticleID,@Barcode,@Size,@isDel,1,0)
  FETCH NEXT FROM i_Barcode_cursor
    INTO @ID,@ArticleID,@Barcode,@Size,@isDel
END
CLOSE i_Barcode_cursor
DEALLOCATE i_Barcode_cursor
GO 

  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Синхронизация таблиц
Ответ #19 - 09. Апреля 2009 :: 06:28
Печать  
Курсор здесь лишний.  Улыбка А так всё правильно.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #20 - 09. Апреля 2009 :: 06:38
Печать  
А как без курсора?  Круглые глаза

Ну в смысле, как без курсора понятно, Вадимко привел решение. Я имею в виду как без курсора в моем решении?
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Синхронизация таблиц
Ответ #21 - 09. Апреля 2009 :: 07:14
Печать  
sadovnikov же писал ещё в #1

Код
Выбрать все
UPDATE Barcode
SET Barcode = i_Barcode.Barcode
	, Size = i_Barcode.Size
	, isDel = i_Barcode.isDel
	, isNew = 1, isUpdate = 0
FROM Barcode
	INNER JOIN i_Barcode ON Barcode.ID = i_Barcode.ID
		AND Barcode.ArticleID = i_Barcode.ArticleID

INSERT Barcode
SELECT i_Barcode.ID
	, i_Barcode.ArticleID
	, i_Barcode.Barcode
	, i_Barcode.Size
	, i_Barcode.isDel
	, 1, 0
FROM i_Barcode
WHERE NOT Exists(
		SELECT *
		FROM Barcode
		WHERE Barcode.ID = i_Barcode.ID
			AND Barcode.ArticleID = i_Barcode.ArticleID) 

  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #22 - 09. Апреля 2009 :: 10:09
Печать  
Действительно...

По поводу решения в #1, я его и использовал. Но вот меня смутило применение WHERE ID IN (Select ID From А),  что то не допер я, что условие в join надо вынести Круглые глаза

з.ы. Сравнил статистику обоих запросов. С курсорами оказывает фигня получается.

                                               Курсор             berezdetsky
Время выполнения клиента      12:25:11            12:24:42            
Статистика по профилю запроса                              
 Количество инструкций INSERT, DELETE и UPDATE      1408            2            705.0000
 Строки, изменяемые инструкциями INSERT, DELETE и UPDATE      1408            1408            1408.0000
 Количество инструкций SELECT      1410            0            705.0000
 Строк, возвращенных инструкциями SELECT      1408            0            704.0000
 Количество транзакций      1408            2            705.0000
Сетевая статистика                              
 Количество циклов обращения к серверу      1            1            1.0000
 TDS-пакетов отправлено клиентом      1            1            1.0000
 TDS-пакетов получено с сервера      19            1            10.0000
 байтов отправлено клиентом      1656            1054            1355.0000
 байтов получено с сервера      76238            41            38139.5000
Статистика по времени                              
 Время обработки клиента      1933            0            966.5000
 Общее время выполнения      2042            218            1130.0000
 Время ожидания при ответе сервера      109            218            163.5000
  
Наверх
 
IP записан
 
kriblya
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 313
Зарегистрирован: 24. Декабря 2007
Re: Синхронизация таблиц
Ответ #23 - 14. Апреля 2009 :: 08:22
Печать  
zenik писал(а) 08. Апреля 2009 :: 13:02:
Это мы в курсе... Мне бы для MSSQL такой ход.

а что в мсскл нет такой конструкции??? (правда не знаю), она помоему из скл92 еще
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Синхронизация таблиц
Ответ #24 - 15. Апреля 2009 :: 08:41
Печать  
Это только в MYSQL, ну может еще где есть. А вот в MSSQL такого нема Печаль Самому не хватает конструкции:
Код
Выбрать все
REPLACE INTO summ (id,date,summa) VALUES ($id,$date,$value) 


Вставка замена по ключу в MYSQL...
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Синхронизация таблиц
Ответ #25 - 15. Апреля 2009 :: 08:46
Печать  
zenik писал(а) 15. Апреля 2009 :: 08:41:
Это только в MYSQL, ну может еще где есть. А вот в MSSQL такого нема Печаль Самому не хватает конструкции:
Код
Выбрать все
REPLACE INTO summ (id,date,summa) VALUES ($id,$date,$value) 


Вставка замена по ключу в MYSQL...

появилось в ms sql 2008  команда  merge
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать