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:
-
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 daGO
. 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. -
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. SebbeneBULK INSERT
è un'operazione non registrata, che tu ci creda o no, può comunque essere inserita all'interno di unBEGIN TRAN
/COMMIT TRAN
blocco. -
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 diOPENROWSET
, 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.