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

Откуда:
Сообщений: 230
Хочу реализовать генерацию ID через доп. таблицу в которой будет хранится имя генератора и значения. Как правильно написать процедуру для получения значений соответствующего генератора что бы не было проблем с транзакциями и блокировками?

Или помогите найти тему в которой это уже обсуждалось ссылка
9 авг 09, 14:27    [7515097]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36803
Правильно - не изобретать велосипед. Все равно с квадратными колесами получится.

Сообщение было отредактировано: 9 авг 09, 15:01
9 авг 09, 15:01    [7515137]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
Loaders
Member

Откуда:
Сообщений: 230
Гавриленко Сергей Алексеевич,

В программе хочу реализовать работу с двумя базами (FireBird, MSSQL). Хотелось что бы механизм получения ID был максимально похожим.
9 авг 09, 15:44    [7515196]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
aleks2
Guest
Loaders

В программе хочу реализовать работу с двумя базами (FireBird, MSSQL). Хотелось что бы механизм получения ID был максимально похожим.


А что, FireBird не имеет механизма IDENTITY?
9 авг 09, 15:55    [7515218]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
Loaders
Member

Откуда:
Сообщений: 230
aleks2,

В FireBird есть генераторы/сиквенсы которыми можно управлять с клиента. Хотелось бы получить что то аналогичное в MSSQL. IDENTITY по религиозным соображениям использовать не хочу.
9 авг 09, 17:00    [7515282]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
aleks2
Guest
Религиозные убеждения могут приводить к чему угодно... но вот только к чему-то ХОРОШЕМУ - не могут.

Нету в MS SQL никаких последовательностей кроме IDENTITY, аминь!

Можете изобретать свой велосипед...
9 авг 09, 17:27    [7515302]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iljy
Member

Откуда:
Сообщений: 8711
Loaders,

генераторы последовательностей в MSSQL симулируются через создание таблицы с единственным полем IDENTITY, затем делается вставка, выбирается SCOPE_IDENTITY, потом удаление вставленой записи. Способ, который изобретаете вы, так или иначе приводит к блокировкам, т.е. если в одной транзакции выбрать значение счетчика, то попытка обрадится к тому же счетчику из другой транзакции приведет к блокировке, пока не будет закомичена первая. Удачи.
9 авг 09, 18:48    [7515360]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
Loaders
Member

Откуда:
Сообщений: 230
iljy,

Такой метод я нашел. Но мне нужно несколько генераторов.
9 авг 09, 19:37    [7515406]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Loaders
iljy,

Такой метод я нашел. Но мне нужно несколько генераторов.
А по нашему форуму не захотели поискать?
Например
9 авг 09, 21:24    [7515540]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iljy
Member

Откуда:
Сообщений: 8711
Loaders,

и что вам мешает завести несколько таких таблиц? Но в целом ваше право, jap правильно сказал - ищите и обрящете, эта тема много раз обсуждалась.
9 авг 09, 22:03    [7515580]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
Loaders
Member

Откуда:
Сообщений: 230
iljy, iap

Искал я по форуме. Ключевые слова генераторы, счетчики. Что то нормального решения не нашел.
10 авг 09, 11:09    [7516349]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
aleks2
Guest
Loaders
iljy, iap

Искал я по форуме. Ключевые слова генераторы, счетчики. Что то нормального решения не нашел.


Нельзя ли, для общего развития, примерчик задачи, где без кучи/парочки последовательностей никак?
10 авг 09, 11:15    [7516377]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
aleks2
Loaders
iljy, iap

Искал я по форуме. Ключевые слова генераторы, счетчики. Что то нормального решения не нашел.


Нельзя ли, для общего развития, примерчик задачи, где без кучи/парочки последовательностей никак?
Могу привести простой пример.
Система обслуживает холдинг, состоящий из нескольких юридических лиц.
По нашим несовершенным законам каждое из этих лиц обязано вести свою собственную нумерацию
исходящих счетов-фактур, причём нумерация должна каждый год начинаться с единицы.
Есть ещё идиотское требование непрерывности этой нумерации (хотя я понимаю, что это такая "борьба" с воровством ).
Кроме того, у каждого из юридических лиц может быть куча филиалов, которым разрешено нумеровать счета-фактуры локально,
Думаю, большинство желаний по поводу генерирования нескольких последовательностей
возникают на почве требований таких вот законов и подзаконных актов о документообороте.
10 авг 09, 11:32    [7516450]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iljy
Member

Откуда:
Сообщений: 8711
Loaders
iljy, iap

Искал я по форуме. Ключевые слова генераторы, счетчики. Что то нормального решения не нашел.


а что собственно вы подразумеваете под "нормальным решением"? сделать так, как хотелось бы вам? Извините, но тут вам придется принять серьезное участие в написании следующих версий скуля;) а если хотите получить нужный результат, используя имеющиеся средства - так хотя бы результат опишите поподробнее!

https://www.sql.ru/forum/actualthread.aspx?tid=681079
вот вам сходу ссылка, где обсуждалась генерация последовательности.

и попробуйте поискать по ключевым словам "последовательность, IDENTITY, генератор".
10 авг 09, 11:42    [7516504]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iljy
Member

Откуда:
Сообщений: 8711
Loaders,

https://www.sql.ru/forum/actualthread.aspx?tid=12200

а здесь обсуждается универсальный вариант создания именованной последовательности.
https://www.sql.ru/forum/actualthread.aspx?bid=1&tid=375408
10 авг 09, 11:48    [7516541]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
Roman S. Golubin
Member

Откуда: 140002
Сообщений: 11541
iap
По нашим несовершенным законам каждое из этих лиц обязано вести свою собственную нумерацию исходящих счетов-фактур, причём нумерация должна каждый год начинаться с единицы.
Есть ещё идиотское требование непрерывности этой нумерации (хотя я понимаю, что это такая "борьба" с воровством ).

Все просто - нумеруешь счета фактуры с "дырками", перед сдачей отчетности генерируешь по "дыркам" счета-фактуры на подставное лицо и анулируешь их все - все сразу розово и пушисто - клиент заказывал товар, но отказалсо
iap

Кроме того, у каждого из юридических лиц может быть куча филиалов, которым разрешено нумеровать счета-фактуры локально

И? Как они их нумеровали до "автомата" - не спрашивал?
10 авг 09, 12:27    [7516850]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Roman S. Golubin
iap
Кроме того, у каждого из юридических лиц может быть куча филиалов, которым разрешено нумеровать счета-фактуры локально

И? Как они их нумеровали до "автомата" - не спрашивал?
Про филиалы спрашиваешь? Им разрешили нумеровать независимо, когда у нас много лет всё уже было "автоматом"
А до этого каждый раз налоговые органы просто входили в положение (филиалы-то от Киева до Владивостока! Связь между ними не всегда была on-line).
10 авг 09, 12:33    [7516901]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
Loaders
Member

Откуда:
Сообщений: 230
Вот написал процедуру. Подскажите какие хинты дописать для блокировок и транзакций, чтобы возникало меньше ошибок.

CREATE TABLE [dbo].[SYS$GENERATOR] (
  [GENERATOR_NAME] varchar(32) NOT NULL,
  [GENERATOR_VALUE] int NOT NULL,
  CONSTRAINT [PK_SYS$GENERATOR] PRIMARY KEY CLUSTERED ([GENERATOR_NAME])
)
GO

CREATE PROCEDURE SYS$GEN_ID(
  @GENERATOR_NAME VARCHAR(32),
  @GENERATOR_STEP INT)
AS
BEGIN
  SET @GENERATOR_NAME = UPPER(@GENERATOR_NAME);
  SET @GENERATOR_STEP = COALESCE(@GENERATOR_STEP, 0);
  DECLARE @GENERATOR_VALUE INT;
  
  BEGIN TRAN GEN;                
  
  IF (@GENERATOR_STEP = 0) BEGIN
    SELECT @GENERATOR_VALUE = GENERATOR_VALUE
    FROM SYS$GENERATOR
    WHERE GENERATOR_NAME = @GENERATOR_NAME;
  END ELSE BEGIN
    UPDATE SYS$GENERATOR
    SET @GENERATOR_VALUE = GENERATOR_VALUE = GENERATOR_VALUE + @GENERATOR_STEP
    WHERE GENERATOR_NAME = @GENERATOR_NAME;
    IF (@@ROWCOUNT = 0) BEGIN        
      SET @GENERATOR_VALUE = 1;
      INSERT INTO SYS$GENERATOR(GENERATOR_NAME, GENERATOR_VALUE)
      VALUES(@GENERATOR_NAME, @GENERATOR_VALUE);                
    END
  END
  
  COMMIT TRAN GEN;
  
  RETURN COALESCE(@GENERATOR_VALUE, 0);
END
GO
10 авг 09, 21:39    [7519657]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iljy
Member

Откуда:
Сообщений: 8711
Loaders,

выполните в двух сессиях одновременно вот это:
begin tran
declare @i int
exec @i = SYS$GEN_ID 'test',1

select @i
10 авг 09, 23:21    [7519811]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
Loaders
Member

Откуда:
Сообщений: 230
iljy,

Вторая сессия ждет завершения первой. Потому я и спросил про блокировки и транзакции, так как не очень хорошо с ними знаком в MSSQL.
10 авг 09, 23:36    [7519847]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
iljy
Member

Откуда:
Сообщений: 8711
Loaders,
и будет ждать. я вам про это в самом первом своем посте сказал. И по другому не получится, потому что вы пытаетесь изменять одну строку из разных транзакций.
10 авг 09, 23:46    [7519882]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
aleks2
Guest
Ну и херню вы рисуете... проще ж надо...

CREATE PROCEDURE SYS$GEN_ID(
  @GENERATOR_NAME VARCHAR(32),
  @GENERATOR_STEP INT)
AS
BEGIN
  DECLARE @GENERATOR_VALUE INT;

  update T SET 
	GENERATOR_VALUE=T.GENERATOR_VALUE+ISNULL(@GENERATOR_STEP, 0), 
	@GENERATOR_VALUE=GENERATOR_VALUE
  from SYS$GENERATOR T
  WHERE T.GENERATOR_NAME = @GENERATOR_NAME;
  
  RETURN COALESCE(@GENERATOR_VALUE, 0);
END
11 авг 09, 06:28    [7520108]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
aleks2
Guest
А главное: что, окромя Геморроя мы приобретаем на таком генераторе по сравнению с IDENTITY?

ТОЛЬКО ГЕМОРРОЙ.
1. Транзакция ДРУГОГО документа будет ЖДАТЬ пока текущая не освободит нумератор, т.е не завершится.
2. Если вам удасться объехать п.1 на кривой козе - вы получите IDENTITY, т.е. потенциальные дырки, когда одна транзакция запросила ID, а потом передумала...
11 авг 09, 06:41    [7520111]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
aleks2
Guest
Если уж непрерывность нумерации нужна как воздух - меняйте логику.

1. Вставляем ПУСТЫЕ документы в необходимом количестве и обеспечиваем механизм периодического или по требованию пополнения (довставки) пустых документов ВНЕ транзакции заполнения документа.
2. Запрещаем удаление на таблице документов.
3. Юзаем пустышки для занесения новых по мере необходимости.
11 авг 09, 06:48    [7520112]     Ответить | Цитировать Сообщить модератору
 Re: Реализация генераторов через таблицу  [new]
rata
Member

Откуда:
Сообщений: 130
iap

Есть ещё идиотское требование непрерывности этой нумерации

Ссылку на нормативную документацию, устанавливающую такое требование - можно?
11 авг 09, 07:26    [7520132]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить