Возможно ли в SQL Server создать функцию, которая могла бы обрабатывать последовательность? - PullRequest
0 голосов
/ 27 ноября 2008

Мы рассматриваем различные варианты переноса нашего уровня персистентности из Oracle в другую базу данных, и мы рассматриваем MS SQL. Однако мы используем последовательности Oracle по всему коду, и поэтому кажется, что перемещение будет головной болью. Я понимаю, что такое @dentity, но это было бы серьезным пересмотром персистентного кода.

Возможно ли в SQL Server создать функцию, которая могла бы обрабатывать последовательность?

Ответы [ 3 ]

1 голос
/ 29 ноября 2008

Я сделал это в прошлом году на проекте. По сути, я только что создал таблицу с именем последовательности, текущего значения и суммы приращения.

Тогда я создал 4 проца:

  • GetCurrentSequence (sequenceName)
  • GetNextSequence (sequenceName)
  • CreateSequence (sequenceName, startValue, incrementAmount)
  • DeleteSequence (sequenceName)

Но есть ограничение, которое вы можете не оценить; Функции не могут иметь побочных эффектов. Таким образом, вы можете создать функцию для GetCurrentSequence (...), но GetNextSequence (...) должен быть процедурой, так как вы, вероятно, захотите увеличить текущее значение последовательности. Однако, если это процесс, вы не сможете использовать его непосредственно в своих операторах вставки.

Так что вместо

insert into mytable(id, ....) values( GetNextSequence('MySequence'), ....);

Вместо этого вам нужно разбить его на 2 строки;

declare @newID int;
exec @newID = GetNextSequence 'MySequence';
insert into mytable(id, ....) values(@newID, ....);

Кроме того, в SQL Server нет механизма, который может делать что-то вроде

MySequence.Current

или

MySequence.Next

Надеюсь, кто-нибудь скажет мне, что я ошибаюсь с вышеуказанными ограничениями, но я почти уверен, что они точны.

Удачи.

1 голос
/ 27 ноября 2008

Это зависит от вашего текущего использования последовательностей в Oracle. Обычно последовательность читается в триггере вставки.

Исходя из вашего вопроса, я предполагаю, что именно постоянный слой генерирует последовательность перед вставкой в ​​базу данных (включая новый pk)

В MSSQL вы можете комбинировать операторы SQL с ';', поэтому для получения столбца идентификаторов вновь созданной записи используйте INSERT INTO ...; SELECT SCOPE_IDENTITY ()

Таким образом, команда для вставки записи возвращает набор записей с одной строкой и одним столбцом, содержащим значение столбца идентификации.

Конечно, вы можете перевернуть этот подход и создать таблицы последовательности (аналогично двойной таблице в Oracle) примерно так:

INSERT INTO SequenceTable (dummy) VALUES ('X');
SELECT @ID = SCOPE_IDENTITY();
INSERT INTO RealTable (ID, datacolumns) VALUES (@ID, @data1, @data2, ...)
0 голосов
/ 28 ноября 2008

Если у вас много кода, вы все равно захотите провести серьезную переработку кода; То, что хорошо работает в Oracle, не всегда хорошо работает в MSSQL. Например, если у вас много курсоров, и вы можете конвертировать их строка за строкой в ​​MSSQL, вы не получите хорошую производительность.

Короче говоря, это нелегкое дело.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...