Поменять текущее значение для TIMESTAMP
Поменять текущее значение для TIMESTAMP
MS SQL 2008 SP3.
Таблица содержит поле типа TIMESTAMP уникальный идентификатор строки - там все автоматически генерируется и подставляется.
База была перенесена с другого сервера, на котором был наработан некоторый объем данных и соответственно TIMESTAMPов.
На новом сервере нумерация началась с начала.
про DBCC CHECKIDENT знаю, но TIMESTAMP не есть идентити.
Вопрос - Как перересеедить значения для TIMESTAMP?
Не очень понятно. TIMESTAMP по умолчанию Getdate(), и при переносе данных все TIMESTAMP's превратились в сегодняшнюю дату?
Тогда нужно взять данные из старой таблицы и сделать UPDATE
TIMESTAMP, увы, но это не GETDATE()
Для него гарантируется уникальность для каждо использования (заполнения поля это типа).
Даже тогда, когда GETDATE() остается без изменений,
TIMESTAMP не есть идентити
значит не ПК, какой-то другой юник индекс. Скорее всего индекс включает ещё нескольколько полей
...тогда я не совсем понимаю, что случилось с TIMESTAMP при переносе. Посредством чего переносили и какой шаг переноса мог отразиться?
На другом сервере установлено другое время? Если хотите, приведите пример "до" - "после"...
Поле этого типа не включено ни в какие индексы.
Перенос делался посредством MS DTS.
Время на серверах синхронизируется автоматически.
какой шаг переноса мог отразиться?
------
??? - все прошло без каких-либо проблем. И вот теперь выползает...
Поле этого типа не включено ни в какие индексы.
тогда чем гарантировано, что это поле юник? Может там процедура какая, например в ДТС пакете, это дело должна была проверять и "поломалась"...
Если у Вас ДТС пакеты регулярно импортируют данные, когда "это" началось? Сравните на win merge ДДЛ таблиц источник-цель, потом данные. Откуда начались отличия.
Потом пошагово обследуйте ДТС - там тоже внутри SQL...
...a исправить как-то так:
UPDATE a
SET a.col = b.col
FROM table1 a
JOIN OPENQUERY ( linked_server ,'...from table1' ) b --или опенроvсет...
ON a.id=b.id
тогда чем гарантировано, что это поле юник?
-----
Microsoft'oм, вообще-то.
Если у Вас ДТС пакеты регулярно импортируют данные
------
Ну какая может быть регулярность при разовом переносе базы?
...a исправить как-то так:
-----
Мысль, конечно, интересная... но...
Вот тебе скриптик с реальной таблички и замена поля типа TIMESTAMP:
DROP TABLE [dbo].[Defaults]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Defaults](
[IDs] [int] IDENTITY(1,1) NOT NULL,
[Active] [varchar](1) NOT NULL DEFAULT ('Y'),
[KeyID] [int] NOT NULL DEFAULT ((1)),
[RecordType] [int] NOT NULL DEFAULT ((0)),
[SequenceNo] [int] NOT NULL,
[RowID] [binary](8) NULL,
[RowTS] [timestamp] NOT NULL,
PRIMARY KEY CLUSTERED
(
[IDs] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Defaults] ON
GO
INSERT INTO [dbo].[Defaults]
([IDs]
,[Active]
,[KeyID]
,[RecordType]
,[SequenceNo]
,[RowID])
VALUES
(1, 'Y', 4, 99, 0, 0x00000000000007E5)
GO
SET IDENTITY_INSERT [dbo].[Defaults] OFF
GO
DECLARE @RowTS AS TIMESTAMP
SELECT @RowTS = RowTS FROM dbo.DEFAULTS WHERE IDs = 1
UPDATE [dbo].[Defaults]
SET [RowTS] = @RowTS + 1
WHERE IDs = 1
GO
Надеюсь после его исполнения кое-что станет понятнее.
Меня интересует как установить начальное значение для вставляемых в [RowTS] значений.
всё, поняла. По привычке думала не про timestamp, а datetime.
Да. Тут даже невозможно отконвертировать в строку
Но! Если в цель-таблице сделать поле не timestamt, a binary(8) - то получается сделать UPDATE:
CREATE TABLE [dbo].[Defaults1](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Active] [varchar](1) NOT NULL,
[KeyID] [int] NOT NULL,
[RecordType] [int] NOT NULL,
[SequenceNo] [int] NOT NULL,
[RowID] [binary](8) NULL,
[RowTS] [binary](8) NOT NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)
SET IDENTITY_INSERT [dbo].[Defaults1] ON
GO
insert into [dbo].[Defaults1]
([ID], [Active], [KeyID], [RecordType], [SequenceNo], [RowID], [RowTS])
select *
FROM [Expert_Questions].[dbo].[Defaults]
SET IDENTITY_INSERT [dbo].[Defaults1] off
GO
DECLARE @RowTS AS binary(8)
SELECT @RowTS = RowTS FROM dbo.DEFAULTS1 WHERE
ID = 1
print @RowTS
UPDATE [dbo].[Defaults1]
SET [RowTS] = @RowTS + 1
WHERE ID = 1
Если в цель-таблице сделать поле не timestamt, a binary(8) - то получается сделать UPDATE
------
Ну это понятно.
Правда появятся ДВА вопроса:
- кто будет заполнять РовТС уникальным значением
- кто будет гарантировать неизменность данного поля
Дело в том, что на РовТС ссылаются из других таблиц.
И кто именно ссылается - зависит от версии используемого клиента.
Клиент - динамический. Т.е. может сменится в процессе работы.
Будет другая база, другие таблицы. Поддерживается это триггерами.
Есть еще версия без базы данных - с хранением всего в файлах...
По-этому делать бинари(8) и дополнительно извращатся - очень не хочется...
Хочется задать начальное значение для TIMESTAMP и забыть об этой маленькой проблеме
DECLARE @RowTS AS binary(8)
SELECT @RowTS = RowTS FROM dbo.DEFAULTS1 WHERE ID = 1
print @RowTS
UPDATE [dbo].[Defaults1]
SET [RowTS] = @RowTS - 1
WHERE ID = 1
SELECT
[ID], [Active], [KeyID], [RecordType], [SequenceNo], [RowID],
convert (timestamp, [RowTS]) as [RowTS]
into [Expert_Questions].[dbo].[Defaults2]
FROM [Expert_Questions].[dbo].[Defaults1]
insert into [Expert_Questions].[dbo].[Defaults2]
( [Active], [KeyID], [RecordType], [SequenceNo], [RowID])
VALUES ( 'Y', 4, 99, 0, 0x00000000000007E5)
а вообще нужно было не ДТС пакетом импортировать, а бекап айншпилен, если всё это одноразово.
Или, ещё лучше, скопировать файлы detach attach
а бекап айншпилен, если всё это одноразово
------
Угу...
Только вот совместимости у бекап/ресторе по версиям не оказалось...
И Я не понял что именно предлагалось делать.
Данные ДТС перегнал без проблем.
Проблема в том, что при вставке новой записи генерируется РовТС
которое уже есть в таблице.
Видимо надо будет дропнуть эту базу, создать новую и загнать туда
данные в том же порядке в каком их создают юзеры.
Немного потеряю, но меньше чем в том бардаке что будет если
оставить как ест'...
Позвольте спросить, какие версии? Это разве что SQL 2000 нельзя сразу в 2014, а нужно сначала в 2008 и потом в 2014. А так нужно просто потом компатибилитетс модус поднять.
Проблема в том, что при вставке новой записи генерируется РовТС которое уже есть в таблице.
Это вот, если сначала в binary(8), потом обратно в timestamp? Сюр какой-то...
И Я не понял что именно предлагалось делать.
- detach database
- скопиривать мдф и лдф
- перенести на нуржный сервер
- attach database на обоих серверах.
Так должна на новом сервере получиться точная копия вместе с таймстемпами.
Это разве что SQL 2000 нельзя сразу в 2014, а нужно сначала в 2008 и потом в 2014.
------
А порядок 2000 => 2008 => 2014 является единственно возможным?
Был откат на более раннюю версию - потому бэкапы не совмещались.
Я ранее тут спрашивал - там версии указаны.
потом обратно в timestamp?
------
Нет, это когда генерится новый TIMESTAMP.
Я потому и спрашиваю не как обойти, а как сделать как надо - задать новый seed для TIMESTAMP.
attach database на обоих серверах
------
Базу 2014 на 2008?
Оригинально - с бэкапа из текста не поднять, а файло на бинарном должно совметится...
Downgrade?
Ну можно 2000->2005. Нужно порыться в документации. Если действителъно 2000, то миграция через бекап и рестор будет сопряжена с ещё бОльшим количеством проблем. Вам нужно будет проверить все процедуры, функционируют ли ещё как раньше. Дам полно проблем с 2000. Аха, поетому то Вы ДТС пакеты используете.