2014-01-17 6 views
1

Мне нужно вставить определенное количество строк в какую-нибудь таблицу со значениями, взятыми из переменных. Я, конечно, могу сделать цикл, вставляя одну строку за раз, но это слишком просто. Я ищу более элегантное решение. Мои текущие мысли касаются порядка INSERT INTO ... SELECT ..., но теперь мне нужен запрос, который будет генерировать количество строк, которые мне нужны. Я попытался написать рекурсивный КТР, чтобы сделать это:Создание набора результатов определенной длины

CREATE FUNCTION ufGenerateRows(@numRows INT = 1) 
RETURNS @RtnValue TABLE 
(
    RowID INT NOT NULL 
) 
AS 
BEGIN 
    WITH numbers AS 
    (
     SELECT 1 as N 
     UNION ALL 
     SELECT N + 1 
     FROM numbers 
     WHERE N + 1 <= @numRows 
    ) 
    INSERT INTO @RtnValue 
     SELECT N 
     FROM numbers 

    RETURN 
END 
GO 

Он работает, но имеет предел глубины рекурсии 100, который не подходит для меня. Можете ли вы предложить альтернативы?

+1

Возможный дубликат [SQL, вспомогательная таблица чисел] (http://stackoverflow.com/questions/10819/sql-auxiliary-table-of-numbers) –

+0

Вы можете установить префикс 'maxrecursion' больше 100, но перекрестные присоединенные CTE лучше. –

ответ

3
  1. всегда использовать префикс в dbo. схемы при создании или ссылки на объекты, особенно функции.
  2. вы должны стремиться создавать встроенные функции, основанные на таблицах, в отличие от табличных функций с несколькими операторами, когда это возможно.
  3. Рекурсивный, CTE примерно наименее эффективный способ получения набора (см это три части серии для гораздо лучше примеры):

Вот один пример:

CREATE FUNCTION dbo.GenerateRows(@numRows INT = 1) 
RETURNS TABLE 
AS 
    RETURN 
    (
    SELECT TOP (@numRows) RowID = ROW_NUMBER() OVER (ORDER BY s1.[number]) 
     FROM master.dbo.spt_values AS s1 
     -- CROSS JOIN master.dbo.spt_values AS s2 
     ORDER BY s1.[number] 
); 

Если вам требуется более ~ 2500 строк, вы можете перекреститься с самим собой или с другой таблицей.

Еще лучше было бы создать таблицу собственных чисел (см., Например, ссылки на приведенные выше ссылки).

1

Не думайте, что итеративно - зацикливание - но установлено - все сразу.

INSERT INTO ... SELECT TOPx ... должны делать то, что вам нужно без повторных вставок.

Я последую примеру, когда я не привязан к своему телефону.

UPDATE:

Что сказал @AaronBertrand. :} A CROSS JOIN в SELECT находится на месте.

+0

'SELECT' от чего? Чтобы получить верхние строки '@ n', мне нужен источник строк, который уже имеет строки' @ n' или более. – n0rd

Смежные вопросы