T-SQL: используйте t-sql во время обычного возврата значения в SELECT - PullRequest
2 голосов
/ 19 июля 2011

У меня есть подпрограмма T-SQL, которая копирует информацию о пользователях из одной таблицы «Радиус» в другую «Теги».Однако, поскольку строки передаются, я также хотел бы включить в INSERT уникальный случайно сгенерированный код (длиной 3 символа).Код генерируется циклом WHILE ниже.Есть ли способ сделать это?

INSERT Tags (UserID, JobID, Code) 
SELECT UserID, @JobID,  ?????
FROM Radius

Уникальный генератор случайных кодов:

WHILE EXISTS (SELECT * FROM Tags WHERE Code = @code)
BEGIN

select @code=@code+char(n) from
(
select top 3 number as n from master..spt_values 
where type='p' and number between 48 and 57 or number between 65 and 90
order by newid()
) 
END

УТОЧНЕНИЕ: причина в том, что я хочу сохранить логику генерации случайных кодов на уровнестека SQL.Реализация этого в коде приложения потребовала бы от меня проверки базы данных каждый раз, когда генерируется потенциальный случайный код, чтобы увидеть, является ли он уникальным.По мере увеличения количества записей кода количество обращений к БД по мере увеличения вероятности будет генерировать больше дублирующих кодов, прежде чем будет сгенерирован уникальный.

Ответы [ 3 ]

5 голосов
/ 19 июля 2011

Часть первая, Генерация таблицы со всеми возможными значениями

DECLARE @i int

CREATE TABLE #AllChars(value CHAR(1))

SET @i=48

WHILE @i<=57
BEGIN
    INSERT INTO #Allchars(value) VALUES(CHAR(@i))
    SET @i=@i+1
END

SET @i=65

WHILE @i<=90
BEGIN
    INSERT INTO #Allchars(value) VALUES(CHAR(@i))
    SET @i=@i+1
END

CREATE TABLE AllCodes(value CHAR(3),
          CONSTRAINT PK_AllChars PRIMARY KEY CLUSTERED(value))

INSERT INTO AllCodes(value)
SELECT AllChars1.Value+AllChars2.Value+AllChars3.Value
FROM #AllChars AS AllChars1,#AllChars AS AllChars2,#AllChars AS AllChars3

Это однократная операция, выполнение которой в SQL Azure занимает около 1 секунды. Теперь, когда у вас есть все возможные значения в таблице, будущие вставки станут чем-то вроде

SELECT
RadiusTable.UserID,
RadiusTable.JobID,
IDTable.Value
FROM 
(
  SELECT ROW_NUMBER() OVER (ORDER BY UserID,JobID) As RadiusRow,
  UserID,JobID
  FROM Radius
) AS RadiusTable INNER JOIN  

(
    SELECT ROW_NUMBER() OVER (ORDER BY newID()) As IDRow,
    Value
    FROM AllCodes
) AS IDTable ON RadiusTable.RadiusRow = IDTable.IDRow

Прежде чем использовать любую из этих схем, вам лучше убедиться, что в вашей таблице не будет более 46656 строк, в противном случае у вас закончатся уникальные значения ID.

4 голосов
/ 19 июля 2011

Я не знаю, возможно ли это и подходит ли для вашей ситуации, но мне кажется, что скалярная функция была бы решением.

1 голос
/ 19 июля 2011

Хорошо, тогда позвольте мне начать сначала.

Это выглядит некрасиво, но это может сработать: newid () внутри функции сервера sql

Принятый ответ.

Ах, это тоже было сделано. Проблема в том, что я использую хранимые процедуры T-SQL, которые вызываются Asp.net. Куда бы я поместил оператор CREATE VIEW? Я не могу добавить его в файл функции.

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