Zdá se, že tato otázka se tu skutečně objevuje často. Mark má správnou (a nejčastěji používanou) odpověď, ale dovolte mi přidat, co mohu, aby to bylo jasnější.
Chybová zpráva je trochu zavádějící. SQL Server vám oznámí, že nemá dostatek paměti ke spuštění dotaz, ale ve skutečnosti to znamená, že nemá dostatek paměti pro analýzu dotazu.
Pokud jde o běh dotaz, SQL Server může použít vše, co chce - gigabajty v případě potřeby. Analýza je jiný příběh; server musí vytvořit strom analýzy a na to je k dispozici jen velmi omezené množství paměti. Nikdy jsem nenašel skutečný limit zdokumentovaný nikde jinde než pro typickou dávku plnou INSERT
příkazy, nemůže zpracovat více než několik MB najednou.
Je mi líto, že vám to říkám, ale nemůžete aby SQL Server spustil tento skript přesně tak, jak je napsán. V žádném případě, ani jak, nezáleží na tom, jaká nastavení vyladíte. Máte však několik možností, jak to obejít:
Konkrétně máte tři možnosti:
-
Použijte
GO
prohlášení. Toho využívají SSMS a různé další nástroje jako oddělovač dávek. Namísto generování jediného stromu analýzy pro celý skript se generují jednotlivé stromy analýzy pro každý segment dávky oddělenéGO
. To je to, co dělá většina lidí, a je velmi jednoduché vytvořit skript transačně bezpečným, jak ukázali jiní a nebudu to zde opakovat. -
Místo generování velkého skriptu pro vložení všech řádků uchovávejte data v textovém souboru (tj. odděleně čárkami). Poté jej importujte pomocí nástroje bcp . Pokud potřebujete, aby to bylo "skriptovatelné" - tj. import musí proběhnout ve stejném skriptu/transakci jako
CREATE TABLE
a poté použijte HROMADNÉ VLOŽENÍ namísto. AčkoliBULK INSERT
je nezaprotokolovaná operace, věřte nebo ne, stále ji lze umístit doBEGIN TRAN
/COMMIT TRAN
blokovat. -
Pokud opravdu, opravdu chcete
INSERT
chcete-li být protokolovanou operací a nechcete, aby vkládání probíhalo v dávkách, můžete použít OPENROWSET otevřít textový soubor, excelový soubor atd. jako ad-hoc "tabulku" a poté ji vložit do nově vytvořené tabulky. Normálně se mi zdráhá doporučovat použitíOPENROWSET
, ale protože se jasně jedná o administrativní skript, není to ve skutečnosti velký problém.
Předchozí komentáře naznačují, že vám číslo 1 nevyhovuje, ačkoli to může být způsobeno pouze nesprávným předpokladem, že to nelze provést v rámci jedné transakce, v takovém případě viz Thomas
odpověď uživatele. Ale pokud jste připraveni jít jinou cestou, doporučuji jít s #2, vytvořit textový soubor a použít BULK INSERT
. Příkladem "bezpečného" skriptu by bylo:
BEGIN TRAN
BEGIN TRY
CREATE TABLE MyTable (...)
BULK INSERT MyTable
FROM 'C:\Scripts\Data\MyTableData.txt'
WITH (
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\r\n',
BATCHSIZE = 1000,
MAXERRORS = 1
)
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
END CATCH
Snad vám to pomůže nasměrovat vás na správnou cestu. Jsem si docela jistý, že to pokrývá všechny vaše dostupné možnosti „v krabici“ – kromě nich byste museli začít psát skutečné aplikační programy nebo skripty shellu, abyste mohli pracovat, a nemyslím si, že tato úroveň složitosti je zde skutečně opodstatněné.