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

Откуда:
Сообщений: 6
Доброго времени суток.
Возникла такая проблема.
есть таблица, которая создаётся вот таким вот манером:
CREATE TABLE [dbo].[HBS_USER](
	[HBS_USER_ID] [bigint] IDENTITY(1, 1) PRIMARY KEY NOT NULL,
        ...............
	[HBS_USER_CREATED] [DATETIME] NOT NULL,
	[HBS_USER_CREATEDBY_ID] [bigint] NOT NULL,
	[HBS_USER_MODIFIED] [DATETIME] NOT NULL,
	[HBS_USER_MODIFIEDBY_ID] [bigint] NOT NULL,
)
GO

ALTER TABLE [dbo].[HBS_USER] WITH CHECK ADD CONSTRAINT [FK_HBS_USER_HBS_USER1] FOREIGN KEY([HBS_USER_CREATEDBY_ID])
REFERENCES [dbo].[HBS_USER] ([HBS_USER_ID])

ALTER TABLE [dbo].[HBS_USER] WITH CHECK ADD CONSTRAINT [FK_HBS_USER_HBS_USER2] FOREIGN KEY([HBS_USER_MODIFIEDBY_ID])
REFERENCES [dbo].[HBS_USER] ([HBS_USER_ID])


естественное положение вещей и маны говорят о том, что выполнить такую штуку не удастся:
INSERT INTO [HBS].[dbo].[HBS_USER]
           (
                    [HBS_USER_ID]
		   ............................
		   ,[HBS_USER_CREATED]
		   ,[HBS_USER_CREATEDBY_ID]
		   ,[HBS_USER_MODIFIED]
		   ,[HBS_USER_MODIFIEDBY_ID])
     VALUES (
		'1'
                .....................
		,GetDate()
		,'1'
		,GetDate()
		,'1')

Но критично подавать на сохранение тип с уже указанным ID, например, в 0. Ну, чтобы выдялось.
Собственно, вопрос звучит так: можно ли этот входящий ID проигнорировать и выставить нужный силами SQL Server'a?
Ещё немного поясню, если не понятно.
Существует тип на C#, в котором есть поле ID. При создании нового объекта User поле ID ставится в 0, и при последующем редактировании (до сохранения в базу) таким и остаётся. Затем выполняется что-то типа save(user) и объект с указанным ID == 0 должен попадать в базу, где ему вместо '0' присваивается валидное, правильное, по фен-шую, ID. Вот, как-то так..
Если кто подскажет - буду очень благодарен.
С уважением, Кирилл А.
28 дек 11, 20:24    [11842310]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
aleks2
Guest
Кирилл Аверкин
естественное положение вещей и маны говорят о том, что выполнить такую штуку не удастся:


Для извращенцев есть
SET IDENTITY_INSERT [ database_name . [ schema_name ] . ] table { ON | OFF }
28 дек 11, 20:31    [11842334]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
Кирилл Аверкин
Member

Откуда:
Сообщений: 6
aleks2,
вот как раз этого мне и надо избежать.
Я хочу, чтобы передавая 0 на сохранение, этот самый ноль ИГНОРИРОВАЛСЯ, и сохраняемый объект получал ID согласно правилам данной таблицы.
28 дек 11, 20:37    [11842349]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
Baddy
Member

Откуда: Харьков
Сообщений: 174
Кирилл Аверкин
aleks2,
вот как раз этого мне и надо избежать.
Я хочу, чтобы передавая 0 на сохранение, этот самый ноль ИГНОРИРОВАЛСЯ, и сохраняемый объект получал ID согласно правилам данной таблицы.

дык не передавайте просто HBS_USER_ID в insert и все будет OK
28 дек 11, 20:39    [11842353]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Кирилл Аверкин,

если IDENTITY так мешает жить, почему бы не создать поле HBS_USER_ID без свойства IDENTITY?
И пишите туда всё, что нужно
28 дек 11, 20:39    [11842354]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
Кирилл Аверкин
Member

Откуда:
Сообщений: 6
Baddy, вилы в том, что бл* этого мне надо перелопатить хренову кучу чужого кода... А этот момент мне тоже не очень улыбается :)
iap, такой вариант меня не устраивает, так как мне неоткуда тогда генерить ID.
28 дек 11, 20:42    [11842362]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
Кирилл Аверкин, триггер повесить, там и прописать вашу извращенную логику.
28 дек 11, 21:09    [11842468]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
Кирилл Аверкин
Member

Откуда:
Сообщений: 6
kDnZP, За извращённую логику спасибо, лучший комплимент моим предшественникам...
То есть, как я понял, самый оптимальный вариант из всего перечисленного, не передавать на сохранение ID вообще... Я правильно всё понял?..
Эх, ну что ж... Пойду закажу пиццу, налью много-много кофе и буду разгребать этот мусор...
Спасибо всем за содействие...
28 дек 11, 21:13    [11842476]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
Кирилл Аверкин, гм... триггером не особо обдурить выходит.


USE tempdb
GO

BEGIN TRAN
CREATE TABLE testTbl( id INT IDENTITY(1,1), f VARCHAR(10))
GO

CREATE TRIGGER tstTrg ON testTbl INSTEAD OF INSERT AS
BEGIN
	SET IDENTITY_INSERT testTbl ON
	INSERT INTO testTbl(id,f)
	SELECT id,f FROM INSERTED WHERE id<>0
	SET IDENTITY_INSERT testTbl OFF
	INSERT INTO testTbl(f)
	SELECT f FROM INSERTED WHERE id=0	
END
GO

-- вот тут, к сожалению, все равно необходим IDENTITY_INSERT, даже не глядя на INSTEAD OF INSERT триггер
SET IDENTITY_INSERT testTbl ON
INSERT INTO testTbl(id,f)
SELECT 10,'tst1' UNION ALL
SELECT 20,'tst2' UNION ALL
SELECT 30,'tst3' UNION ALL
SELECT 0,'tst4' UNION ALL
SELECT 0,'tst5'
SET IDENTITY_INSERT testTbl OFF

SELECT * FROM testTbl

ROLLBACK


Но все равно - триггер можно навесить на вьюху, совподающую по имени с таблицей, а таблицу при этом переименовать в нечто другое... Разруливать все на уровне триггера. Но это латание дыр проекта на C# средствами SQL Server. Может не самый правильный вариант. При доступности исходников C# - поправить их было бы вернее.
28 дек 11, 21:39    [11842543]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
Кирилл Аверкин
Member

Откуда:
Сообщений: 6
kDnZP, Ну, в общем, особого выбора нет. займусь перебиранием проекта по кусочкам )
28 дек 11, 21:42    [11842553]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
Кирилл Аверкин,

Таблицу переименовать. Вместо таблицы использовать вьюху с инстедными триггерами.
?
28 дек 11, 22:21    [11842668]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
интеграция
Guest
aleks2,

This is true
29 дек 11, 00:50    [11843114]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
интеграция
aleks2,

This is true

Тру-то канешна тру. Но на всяк случай полноценный пример:
USE tempdb
GO

BEGIN TRAN
CREATE TABLE testTbl_( id INT IDENTITY(1,1), f VARCHAR(10))
GO

CREATE VIEW testTbl AS
SELECT id, f FROM testTbl_
GO

CREATE TRIGGER tstTrg ON testTbl INSTEAD OF INSERT AS
BEGIN
	SET IDENTITY_INSERT testTbl_ ON
	INSERT INTO testTbl_(id,f)
	SELECT id,f FROM INSERTED WHERE id<>0
	SET IDENTITY_INSERT testTbl_ OFF
	INSERT INTO testTbl_(f)
	SELECT f FROM INSERTED WHERE id=0	
END
GO

-- т.к. на самом-то деле вставка во вьюху, то можно делать как нравится.
INSERT INTO testTbl(id,f)
SELECT 10,'tst1' UNION ALL
SELECT 20,'tst2' UNION ALL
SELECT 30,'tst3' UNION ALL
SELECT 0,'tst4' UNION ALL
SELECT 0,'tst5'

SELECT * FROM testTbl

ROLLBACK
 
29 дек 11, 01:40    [11843199]     Ответить | Цитировать Сообщить модератору
 Re: проигнорировать входящее значение с identity  [new]
Кирилл Аверкин
Member

Откуда:
Сообщений: 6
Ребят, спасибо всем. За помощ и т.д. Решаю вопрос посредством перетрахивания самописной "ORM". Я уже довольно близко к решению, просто хотелось чего-то более.. Ммм. Однострочного :)
29 дек 11, 02:26    [11843290]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить