Domanda

Voglio passare alle tabelle nel miglior modo possibile.
Ho una tabella IpToCountry e ne creo una nuova su base settimanale in base a un file CSV esterno da me importato.

Il modo più veloce che ho trovato per effettuare il passaggio è stato il seguente:

sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go

Il problema è che è possibile accedere alla tabella tra.
Come affrontare questo problema in SQL?
Nel considerare l'utilizzo di sp_getapplock e sp_releaseapplock, ma voglio mantenere la lettura dalla funzione tabella il più rapidamente possibile.

È stato utile?

Soluzione

Supponendo che non sia possibile aggiornare / inserire nella tabella esistente, perché non avvolgere tutti gli accessi alla tabella usando un visualizza ?

Ad esempio, potresti inizialmente archiviare i tuoi dati in una tabella chiamata IpToCountry20090303 e la tua vista sarebbe simile a questa:

CREATE VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090303

Quando arrivano i nuovi dati, è possibile creare e popolare la tabella IpToCountry20090310 . Una volta popolata la tabella, aggiorna la visualizzazione:

ALTER VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090310

Lo switch sarà completamente atomico, senza richiedere alcun blocco o transazione espliciti. Una volta che la vista è stata aggiornata, puoi semplicemente eliminare la vecchia tabella (o conservarla se preferisci).

Altri suggerimenti

Un altro metodo per implementare ciò che stai cercando di ottenere sarebbe l'uso del partizionamento delle tabelle, una tecnica disponibile nell'edizione Enterprise di SQL Server.

Il nome della tabella può rimanere lo stesso. Al termine dell'importazione della tabella, è sufficiente cambiare la partizione contenente i vecchi dati e passare alla nuova partizione.

Il seguente white paper contiene tutte le informazioni necessarie per iniziare.

http://msdn.microsoft.com/en-us/library /ms345146.aspx

Saluti, John

Ho avuto problemi a far funzionare su larga scala le funzioni di partizionamento. CREATE e DROP PARTITION sono operazioni di blocco e hai poco controllo sul blocco e, se non riesce a ottenere un blocco, fallirà con un livello di gravità 16 e ucciderà la tua connessione, che non puoi intercettare e riprovare senza ristabilire la connessione. Ma potrebbe funzionare bene per te. Inoltre, è richiesta MSS Enterprise Edition, non è possibile utilizzare SE - potrebbe essere troppo per alcuni negozi più piccoli o più economici.

Ho anche trovato la vista redef per bloccare su larga scala (= volume di transazione + volume puro di dati costantemente inseriti, nel mio caso) su tabelle e oggetti di sistema, quindi quelle operazioni possono bloccarsi su cose come reindicizzare e DTCC - e in un caso, in particolare con un utente in SSMS (di tutte le cose) che cerca di sfogliare le viste in Esplora oggetti (qualcuno deve dire a quei ragazzi di READPAST). Ancora una volta, il tuo chilometraggio può variare.

Al contrario, sp_rename funziona bene per me su larga scala: ti dà il controllo sul blocco e sulla portata di esso. Per risolvere il problema di blocco prima dello scambio, provalo come mostrato di seguito. A prima vista, questo sembra avere lo stesso problema di scala ad alto volume ... ma non l'ho visto in pratica. Quindi, funziona per me ... ma ancora una volta, le esigenze e le esperienze di ognuno sono diverse.

DECLARE @dummylock bit 
BEGIN TRANSACTION 
BEGIN TRY
   -- necessary to obtain exclusive lock on the table prior to swapping
   SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM A WITH (TABLOCKX))
   -- may or may not be necessary in your case
   SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM B WITH (TABLOCKX))
   exec sp_rename 'A', 'TEMP'
   exec sp_rename 'B', 'A'
   exec sp_rename 'TEMP', 'B'
   COMMIT TRANSACTION
END TRY
BEGIN CATCH
   -- other error handling here if needed
   ROLLBACK TRANSACTION 
END CATCH

Cosa succede a IpToCountryOld? Lo butti via? In tal caso, perché non troncare IpToCountry e importare i miei nuovi dati.

Se hai bisogno di conservare i dati, che ne dici di memorizzare la data di caricamento sulla tabella e di archiviare "corrente"? caricare la data da qualche parte da utilizzare in una clausola WHERE? Quindi si cambia la data corrente quando i dati vengono caricati correttamente.

Non dici quale DB stai usando, quindi non so quanto sia utile, ma hai delle procedure memorizzate che fanno riferimento alla tabella? Tieni presente che su alcune piattaforme gli SP vengono compilati utilizzando riferimenti interni alle tabelle che non cambieranno con una ridenominazione, quindi c'è il rischio che gli SP non raccolgano i tuoi nuovi dati senza una ricompilazione. Lo stesso può valere per le visualizzazioni e le query analizzate archiviate.

Non è possibile eseguire l'importazione in una tabella durante le ore non lavorative?

O perché non fare semplicemente un aggiornamento dei dati, ad esempio aggiornare i record esistenti e aggiungerne di nuovi in ??base al record in base al record mentre si esegue il ciclo per importare i dati. Ciò consentirebbe al tavolo di rimanere attivo e ridurrebbe l'impatto complessivo dell'aggiunta e del rilascio di tavoli completi.

Qual è la struttura dei dati importati, il design della tabella, il formato, il PK, ecc.? Da ciò potremmo essere in grado di darti una risposta migliore.

Si è appena verificato un problema simile lavorando su una tabella di gestione temporanea con problemi di ridimensionamento con blocchi adeguati.

Ovunque venga fatto riferimento alla tabella, è possibile chiamare una procedura memorizzata che richiede il nome della tabella.

La procedura memorizzata creerebbe facoltativamente le nuove tabelle o restituirebbe le vecchie tabelle in base ai parametri forniti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top