Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Errore 701 di SQL Server 2005 - memoria insufficiente

Questa domanda in realtà sembra sorgere ogni tanto qui. Segna ha la risposta corretta (e più comunemente utilizzata), ma vorrei provare ad aggiungere ciò che posso per renderlo più chiaro.

Il messaggio di errore è un po' fuorviante. SQL Server ti dice che non ha memoria sufficiente per eseguire la query, ma in realtà significa che non ha memoria sufficiente per analizzare la domanda.

Quando si tratta di correre la query, SQL Server può utilizzare tutto ciò che vuole - gigabyte se necessario. L'analisi è un'altra storia; il server deve creare un albero di analisi e c'è solo una quantità molto limitata di memoria disponibile per questo. Non ho mai trovato il limite effettivo documentato da nessuna parte tranne che per un tipico batch pieno di INSERT istruzioni, non può gestire più di pochi MB alla volta.

Quindi mi dispiace dirtelo ma tu non puoi fare in modo che SQL Server esegua questo script esattamente come è scritto. Assolutamente no, no come, non importa quali impostazioni modifichi. Tuttavia, hai una serie di opzioni per aggirarlo:

Nello specifico, hai tre opzioni:

  1. Usa GO dichiarazioni. Viene utilizzato da SSMS e vari altri strumenti come separatore batch. Invece di generare un singolo albero di analisi per l'intero script, vengono generati singoli alberi di analisi per ogni segmento del batch separato da GO . Questo è ciò che fa la maggior parte delle persone ed è molto semplice rendere lo script sicuro per le transazioni, come altri hanno dimostrato e non lo ripeterò qui.

  2. Invece di generare un enorme script per inserire tutte le righe, mantieni i dati in un file di testo (cioè separati da virgole). Quindi importalo utilizzando l'utilità bcp . Se è necessario che sia "scriptabile", ovvero l'importazione deve avvenire nello stesso script/transazione di CREATE TABLE dichiarazione, quindi utilizzare BULK INSERT invece. Sebbene BULK INSERT è un'operazione non registrata, che tu ci creda o no, può comunque essere inserita all'interno di un BEGIN TRAN / COMMIT TRAN blocco.

  3. Se davvero vuoi davvero il INSERT per essere un'operazione registrata e non si desidera che gli inserimenti avvengano in batch, è possibile utilizzare OPENROWSET per aprire un file di testo, un file excel, ecc. come una "tabella" ad hoc, quindi inserirlo nella tabella appena creata. Normalmente sono restio a raccomandare l'uso di OPENROWSET , ma poiché si tratta chiaramente di uno script amministrativo, non è un grosso problema.

I commenti precedenti suggeriscono che sei a disagio con #1, anche se ciò potrebbe essere dovuto solo a un presupposto errato che non possa essere eseguito in una singola transazione, nel qual caso vedi Thomas la risposta. Ma se sei pronto ad andare in un altro modo, ti suggerisco di andare con il n. 2, creando un file di testo e usando BULK INSERT . Un esempio di script "sicuro" potrebbe essere:

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

Spero che questo ti aiuti a metterti sulla strada giusta. Sono abbastanza sicuro che questo copra tutte le tue opzioni "in the box" disponibili - oltre a queste, dovresti iniziare a scrivere programmi applicativi reali o script di shell per fare il lavoro, e non penso che il livello di complessità sia davvero garantito qui.