sql >> Databáze >  >> RDS >> Sqlserver

SQL Server 2005 Chyba 701 – nedostatek paměti

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:

  1. 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.

  2. 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čkoli BULK INSERT je nezaprotokolovaná operace, věřte nebo ne, stále ji lze umístit do BEGIN TRAN / COMMIT TRAN blokovat.

  3. 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é.



  1. Přeměňte výsledek databáze na pole

  2. duplicitní klíč postgresql porušuje jedinečné omezení

  3. Použití více databází a schémat POSTGRES se stejným modelem Flask-SQLAlchemy

  4. Jak vyplnit díry v polích automatického přírůstku?