Вставка n записей с помощью T-SQL

Я действительно не понимаю некоторые из приведенных здесь ответов (извините за это). Например, опрос с высоким рейтингом не возвращает архитектуру Windows, а дает вам процессорную архитектуру.

Самый безопасный вариант - запрашивать значение BuildLabEx из реестр.

Определить x86 (intel) или x86-64 (amd)

reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx" | >nul find /i ".x86fre."   && set "_ARCH_=x86" || set "_ARCH_=x86-64"

Определить x86 (intel ), x86-64 (amd) или arm

set "_ARCH_=unknown"
reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx" | >nul find /i ".x86fre."   && set "_ARCH_=x86" 
reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx" | >nul find /i ".amd64fre." && set "_ARCH_=x86-64" 
reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx" | >nul find /i ".armfre."   && set "_ARCH_=arm" 

Альтернативный вариант (упомянутый ранее)

if defined ProgramFiles(x86) ( set "_ARCH_=x86-64" ) else ( set "_ARCH_=x86" )

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

13
задан Cade Roux 30 June 2009 в 13:42
поделиться

8 ответов

Это подход, который я использую, и он лучше всего подходит для моих целей и с использованием SQL 2000. Поскольку в моем случае он находится внутри UDF, я не могу использовать временные таблицы ## или #, поэтому Я использую табличную переменную. Я делаю:

DECLARE @tblRows TABLE (pos int identity(0,1), num int) 
DECLARE @numRows int,@i int


SET @numRows = DATEDIFF(dd,@start,@end) + 1
SET @i=1

WHILE @i<@numRows
begin
    INSERT @tblRows SELECT TOP 1 1 FROM sysobjects a

    SET @i=@i+1
end
3
ответ дан 1 December 2019 в 19:02
поделиться

Для этого можно использовать инструкцию WHILE:

declare @i int
declare @rows_to_insert int
set @i = 0
set @rows_to_insert = 1000

while @i < @rows_to_insert
    begin
    INSERT INTO #temp VALUES (@i)
    set @i = @i + 1
    end
11
ответ дан 1 December 2019 в 19:02
поделиться

Если вы используете SQL 2005 или новее, вы можете использовать рекурсивный CTE для получения списка дат или чисел ...

with MyCte AS
    (select   MyCounter = 0
     UNION ALL
     SELECT   MyCounter + 1
     FROM     MyCte
     where    MyCounter < DATEDIFF(d,'2009-01-01',getdate()))
select MyCounter, DATEADD(d, MyCounter, '2009-01-01')
from   MyCte 
option (maxrecursion 0)


/* output...
MyCounter   MyDate
----------- -----------------------
0           2009-01-01 00:00:00.000
1           2009-01-02 00:00:00.000
2           2009-01-03 00:00:00.000
3           2009-01-04 00:00:00.000
4           2009-01-05 00:00:00.000
5           2009-01-06 00:00:00.000
....
170         2009-06-20 00:00:00.000
171         2009-06-21 00:00:00.000
172         2009-06-22 00:00:00.000
173         2009-06-23 00:00:00.000
174         2009-06-24 00:00:00.000

(175 row(s) affected)

*/
18
ответ дан 1 December 2019 в 19:02
поделиться

вы можете использовать перекрестное соединение

select top 100000 row_number() over(order by t1.number)-- here you can change 100000 to a number you want or a variable
from   master.dbo.spt_values t1
       cross join master.dbo.spt_values t2
2
ответ дан 1 December 2019 в 19:02
поделиться

Если у вас есть заранее созданная таблица чисел, просто используйте ее:

SELECT *
FROM numbers
WHERE number <= DATEDIFF(d,'2009-01-01',getdate())

Существует любое количество методов для построения таблицы чисел в первую очередь (используя здесь методы), но один раз он построен и проиндексирован, его больше не строить.

2
ответ дан 1 December 2019 в 19:02
поделиться

Добавьте следующее перед вызовом xl.Quit ():

GC.Collect(); 
GC.WaitForPendingFinalizers(); 

Вы также можете использовать Marshal.FinalReleaseComObject () в вашем методе NAR вместо ReleaseComObject. ReleaseComObject уменьшает счетчик ссылок на 1, в то время как FinalReleaseComObject освобождает все ссылки, поэтому счетчик равен 0.

Итак, ваш блок finally будет выглядеть так:

finally
{
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 

    NAR(wSheet);
    if (wBook != null)
        wBook.Close(false, m_objOpt, m_objOpt);
    NAR(wBook);
    xl.Quit();
    NAR(xl);
}

Обновленный метод NAR:

private void NAR(object o)
{
    try
    {
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(o);
    }
    catch { }
    finally
    {
        o = null;
    }
}

Я исследовал это некоторое время назад, и в примерах я обнаружил, что обычно вызовы, связанные с сборщиком мусора, выполняются в конце после закрытия приложения. Однако есть MVP (Майк Розенблюм), который упоминает, что его следует вызвать в начале. Я пробовал оба способа, и они сработали. Я также попробовал это без WaitForPendingFinalizers, и он работал, хотя ничего не должно было повредить. YMMV.

0
ответ дан 1 December 2019 в 19:02
поделиться

Вы можете делать то, что предлагает PinalDave :

INSERT INTO MyTable (FirstCol, SecondCol)
SELECT 'First' ,1
UNION ALL
SELECT 'Second' ,2
UNION ALL
SELECT 'Third' ,3
UNION ALL
SELECT 'Fourth' ,4
UNION ALL
SELECT 'Fifth' ,5
GO
0
ответ дан 1 December 2019 в 19:02
поделиться

В целом намного быстрее удваивать количество строк на каждой итерации

CREATE TABLE dbo.Numbers(n INT NOT NULL PRIMARY KEY)
GO
DECLARE @i INT;
SET @i = 1;
INSERT INTO dbo.Numbers(n) SELECT 1;
WHILE @i<128000 BEGIN
  INSERT INTO dbo.Numbers(n)
    SELECT n + @i FROM dbo.Numbers;
  SET @i = @i * 2;
END; 

Я намеренно не ВКЛЮЧИЛ NOCOUNT, чтобы вы могли видеть, как он вставляет 1,2,4,8 строки

3
ответ дан 1 December 2019 в 19:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: