Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Дельта структур БД  [new]
Geo
Member

Откуда:
Сообщений: 6885
Добрый вечер.

Подскажите, пожалуйста:

Имеются две версии одной БД. Предположим, в виде двух одноименных баз на двух MS SQL Server 2000 (в идеале одна на сервере, а другая в виде backup'а). Есть ли возможность какими-нибудь штатными способами увидить разницу между ними? Нужна структура, но интересно и данными. Хотя второе, вероятно, в штатных не предусмотрено, судя по горячей десятке.

Благодарю.
14 окт 04, 22:18    [1035472]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
Alexey_DBA
Member

Откуда: Киев
Сообщений: 116
Можно попробывать сравнить 2 версии структуры Power Designer'ом.
Для этого надо сделать reverse engineering одной и другой БД в Power Designer.
19 окт 04, 22:42    [1046622]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
www.fun4me.narod.ru
Member

Откуда: Moscow
Сообщений: 2407
А если скрипт сгенерить с обеих баз и diff'ом их сравнить?
20 окт 04, 09:34    [1046952]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
Geo
Member

Откуда:
Сообщений: 6885
Ох, не ожидал, что так далеко уехавший топик получит ответы. Спасибо еще раз.
Power Designer'ом не пользовался, попробую.
А diff - это кто? Нечто вроде compare (или fcomp - как бишь их там в досе звали)? Тоже поищу.
Вообще-то, по прошедему времени, подумал, что в сущности, сравнение структур ничем не отличается от сравнения таблиц. Коль скоро нет второго, не нужно ожидать и первого. :)
Однако, если наткнусь на подобие панацеи, сюда напишу.
21 окт 04, 00:29    [1050246]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
Alex.Czech
Guest
Сравнение двух таблиц - не такая уж сложная задача, мне представляется, если конечно у них одинаковая структура и есть первичный ключ. Можно написать функцию (хоть даже и на T-SQL), которая сгенерит соотв.скрипт. Можно даже довольно быстро ее написать :)
21 окт 04, 00:43    [1050256]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
Geo
Member

Откуда:
Сообщений: 6885
Ой ли? В сущности, это самописная репликация.
21 окт 04, 01:47    [1050288]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
Alex Antonoff
Member

Откуда: Из лесу вестимо
Сообщений: 1251
Попробуйте redgate SQL tools. Там есть SQL Compare он делает именно то, что вам нужно без всяких лишних действий. Есть триальная версия на 14 дней. Сам пользуюсь и вам рекомендую.
21 окт 04, 07:19    [1050352]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
Alex Antonoff
Member

Откуда: Из лесу вестимо
Сообщений: 1251
Кстати данные она тоже позволяет сравнивать ...
21 окт 04, 07:41    [1050367]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
Alex.Czech
Guest
Geo
Ой ли? В сущности, это самописная репликация.


Неа. В сущности, это небольшая часть самописной репликации, не предполагающая автоматического сведения данных никакого. Маленький-маленький фрагмент
21 окт 04, 09:55    [1050630]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
SM
Member

Откуда: Calgary, Canada
Сообщений: 219
Мы пользовались Embarcadero Change Manager
21 окт 04, 10:27    [1050725]     Ответить | Цитировать Сообщить модератору
 Re: Дельта структур БД  [new]
DronVS
Member

Откуда:
Сообщений: 41
я написал для таблиц следующее:

DECLARE @base_name_from varchar(50), @base_name_to varchar(50), @filter_mask int, @tabl_name varchar(250)
SET NOCOUNT ON
SELECT @base_name_from = '@base_name_from@', @base_name_to = '@base_name_to@'
SELECT @filter_mask=12, @tabl_name='%'


CREATE TABLE #table_from (t_name varchar(250), c_name varchar(250), c_type int, c_type_name varchar(50), c_length int, c_cdefault int, c_prec int, c_scale int, c_isnull int)
CREATE TABLE #table_to (t_name varchar(250), c_name varchar(250), c_type int, c_type_name varchar(50), c_length int, c_cdefault int, c_prec int, c_scale int, c_isnull int)
CREATE TABLE #result_tbl (dif_type int, t_name varchar(250), mes_differens varchar (500), is_group_row int)

EXEC('INSERT INTO #table_from (t_name, c_name, c_type, c_type_name, c_length, c_cdefault, c_prec, c_scale, c_isnull) '+
' select sys_obj.name, sys_col.name, sys_col.xusertype, sys_type.name, sys_col.length, sys_col.cdefault, sys_col.prec, sys_col.scale, sys_col.isnullable '+
' from '+@base_name_from+'.dbo.sysobjects sys_obj '+
' join '+@base_name_from+'.dbo.syscolumns sys_col ON sys_col.id = sys_obj.id '+
' join '+@base_name_from+'.dbo.systypes sys_type ON sys_type.xusertype = sys_col.xusertype '+
' where sys_obj.xtype = ''U'' and UPPER(sys_obj.name) like UPPER('''+@tabl_name+''') ')

EXEC('INSERT INTO #table_to (t_name, c_name, c_type, c_type_name, c_length, c_cdefault, c_prec, c_scale, c_isnull) '+
' select sys_obj.name, sys_col.name, sys_col.xusertype, sys_type.name, sys_col.length, sys_col.cdefault, sys_col.prec, sys_col.scale, sys_col.isnullable '+
' from '+@base_name_to+'.dbo.sysobjects sys_obj '+
' join '+@base_name_to+'.dbo.syscolumns sys_col ON sys_col.id = sys_obj.id '+
' join '+@base_name_to+'.dbo.systypes sys_type ON sys_type.xusertype = sys_col.xusertype '+
' where sys_obj.xtype = ''U'' and UPPER(sys_obj.name) like UPPER('''+@tabl_name+''') ')

DECLARE @is_check_exists int, @is_check_diff int
SET @is_check_exists = (@filter_mask / 4) % 2
SET @is_check_diff = (@filter_mask / 8) % 2

IF @is_check_exists = 1
BEGIN
--1. Таблицы которые есть на @base_name_from но нет на @base_name_to
INSERT INTO #result_tbl (dif_type, mes_differens, t_name, is_group_row)
SELECT DISTINCT 1, 'Есть на: "'+ @base_name_from + '" но нет на: "'+@base_name_to +'"', tf.t_name, 2
FROM #table_from tf
LEFT OUTER JOIN #table_to tt ON tt.t_name = tf.t_name
WHERE tt.t_name IS NULL

--2. Таблицы которые есть на @base_name_to но нет на @base_name_from
INSERT INTO #result_tbl (dif_type, mes_differens, t_name, is_group_row)
SELECT DISTINCT 2, 'Есть на: "'+ @base_name_to + '" но нет на: "'+@base_name_from +'"', tt.t_name, 2
FROM #table_to tt
LEFT OUTER JOIN #table_from tf ON tf.t_name = tt.t_name
WHERE tf.t_name IS NULL
END

IF @is_check_diff = 1
BEGIN
--4-5. Таблицы которые есть но различаються кол-во полей.
-- Понял что просто кол-во нельзя. потому как может быт там одно поле а другово может не быть.
INSERT INTO #result_tbl (dif_type, mes_differens, t_name)
SELECT DISTINCT 4, tf.c_name, tf.t_name
FROM #table_from tf
JOIN #table_to tt ON tt.t_name = tf.t_name
LEFT OUTER JOIN #table_to tt1 ON tt1.t_name = tt.t_name AND tt1.c_name = tf.c_name
WHERE tt1.c_name IS NULL
INSERT INTO #result_tbl (dif_type, mes_differens, t_name)
SELECT DISTINCT 5, tt.c_name, tt.t_name
FROM #table_to tt
JOIN #table_from tf ON tt.t_name = tf.t_name
LEFT OUTER JOIN #table_from tf1 ON tf.t_name = tf1.t_name AND tt.c_name = tf1.c_name
WHERE tf1.c_name IS NULL

--6. Таблицы которые есть но различаються типом данных.
INSERT INTO #result_tbl (dif_type, t_name, mes_differens)
SELECT DISTINCT 6, tf.t_name,
tt.c_name +
CASE
WHEN tt.c_type_name <> tf.c_type_name THEN ' (тип: на источнике-'+tf.c_type_name+' на получателе-'+tt.c_type_name+')'
ELSE CASE
WHEN tt.c_length <> tf.c_length THEN ' (длинна: на источнике-'+tf.c_type_name+'('+CAST(tf.c_length as varchar)+') на получателе-'+tt.c_type_name+'('+CAST(tt.c_length as varchar)+') )'
ELSE ' (размерность: на источнике-'+tf.c_type_name+'('+CAST(ISNULL(tf.c_prec,0) as varchar)+':'+CAST(ISNULL(tf.c_scale,0) as varchar)+') '+
' на получателе-'+tf.c_type_name+'('+CAST(ISNULL(tt.c_prec,0) as varchar)+':'+CAST(ISNULL(tt.c_scale,0) as varchar)+') )'
END
END
FROM #table_from tf
JOIN #table_to tt ON tt.t_name = tf.t_name AND tt.c_name = tf.c_name
WHERE tt.c_type_name <> tf.c_type_name OR tt.c_length <> tf.c_length OR tt.c_prec <> tf.c_prec OR tt.c_scale <> tf.c_scale

--7. Таблицы которые есть но различаються допустимостью IS NULL
INSERT INTO #result_tbl (dif_type, t_name, mes_differens)
SELECT DISTINCT 7, tf.t_name,
tt.c_name + ' (на источнике-'+cast(tf.c_isnull as varchar)+' на получателе-'+cast(tt.c_isnull as varchar)+')'
FROM #table_from tf
JOIN #table_to tt ON tt.t_name = tf.t_name AND tt.c_name = tf.c_name
WHERE tt.c_isnull <> tf.c_isnull

--8. Таблицы которые есть но различаються Есть Нет ДИфайна
INSERT INTO #result_tbl (dif_type, t_name, mes_differens)
SELECT DISTINCT 8, tf.t_name,
tt.c_name + CASE WHEN tf.c_cdefault > 0 THEN ' (на источнике-1 на получателе-0)' ELSE ' (на источнике-0 на получателе-1)' END
FROM #table_from tf
JOIN #table_to tt ON tt.t_name = tf.t_name AND tt.c_name = tf.c_name
WHERE (tt.c_cdefault = 0 AND tf.c_cdefault > 0) OR
(tt.c_cdefault > 0 AND tf.c_cdefault = 0)
END

UPDATE #result_tbl
SET is_group_row = 0
WHERE is_group_row IS NULL

INSERT INTO #result_tbl (dif_type, t_name, mes_differens, is_group_row)
SELECT
dif_type, t_name,
CASE dif_type
WHEN 4 THEN ' Поля отсутствующие на получателе "'+@base_name_to+ '": '
WHEN 5 THEN ' Поля отсутствующие на источнике "' + @base_name_from + '": '
WHEN 6 THEN ' Поля с измененым типом данных:'
WHEN 7 THEN ' Поля с изменненым значением (AllowNulls):'
WHEN 8 THEN ' Поля с изменненым значением (DefaultValueExists):'
END,
1
FROM #result_tbl
WHERE dif_type > 2
GROUP BY dif_type, t_name

INSERT INTO #result_tbl (dif_type, t_name, mes_differens, is_group_row)
SELECT 3, t_name, 'Изменения в таблице...', 2
FROM #result_tbl
WHERE dif_type > 3
GROUP BY t_name

SELECT dif_type, t_name, mes_differens, is_group_row
FROM #result_tbl
ORDER BY t_name, dif_type, mes_differens

DROP TABLE #table_from
DROP TABLE #table_to
DROP TABLE #result_tbl
21 окт 04, 10:58    [1050823]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить