2010-10-15 23 views
7

Abbiamo un database con un gruppo di tabelle larghe (40-80 colonne ciascuna) e appena trovato un bug che ha introdotto valori NULL in circa 500 dei record. I valori NULL possono apparire in qualsiasi colonna (sono tutte colonne integer, vedi immagine sotto) ma questi valori NULL stanno causando problemi con uno dei nostri sistemi di reporting che non possono essere modificati facilmente. Abbiamo bisogno di sostituire i valori NULL con uno specifico valore statico (in questo caso 99), ma poiché questa modifica deve essere fatta su una base per colonna per oltre 250 colonne diverse preferisco non scrivere singoli script TSQL aggiornando ogni colonna uno da uno.Aggiorna tutti i valori SQL NULL in più colonne utilizzando la clausola WHERE della colonna?

Al momento il mio cervello è troppo fritto per pensare a una soluzione intelligente, quindi la mia domanda è: come posso eseguire questa operazione su tutte le colonne di una tabella (o meglio ancora su più tabelle) utilizzando una query SQL semplice e leggibile. Posso isolare i record abbastanza facilmente utilizzando una catena di WHERE (Answer_1 IS NULL) OR (Answer_2 IS NULL) OR ... o anche da numeri di AdministrationID per ogni tabella, ma questo trucco non funzionerà quando si aggiorna come clausola where per riga non per colonna. Qualche consiglio?

Ecco una query di esempio che mostra alcuni dei record da 4 tavoli diversi: Sample

+1

Questo fa male, davvero male. –

+0

Suppongo che aggiungerei un vincolo non nullo con un valore predefinito 99 su ciascuna colonna? – njzk2

+0

Guardo questo e mi chiedo perché le colonne non sono le seguenti: AdministrationID, InstrumentID, ID risposta, valore. Diamine, potresti persino aggiungere un altro id in modo da poter unire tutti quei tavoli in 1 ... –

risposta

21

non c'è alcuna convenzione per questo - se si vuole registrazioni dei processi solo dove rispettive colonne sono NULL, è necessario utilizzare:

WHERE Answer_1 IS NULL 
    OR Answer_2 IS NULL 
    OR ... 

Ma si potrebbe usare questo nell'istruzione UPDATE:

UPDATE YOUR_TABLE 
    SET col1 = COALESCE(col1, 99), 
     col2 = COALESCE(col2, 99), 
     col3 = ... 

la logi c è che il valore sarà aggiornato a 99 solo se il valore della colonna è NULL, a causa di come funziona COALESCE, restituendo il primo valore non NULL (elaborando l'elenco fornito da sinistra a destra).

+0

+1 - Devo essere stanco, stavo cercando di farlo con un'istruzione 'CASE' ... O_o – LittleBobbyTables

+0

+1 per il Coalesce. –

+2

E sul lato positivo, le colonne sono tutte in formato 'Risposta_', quindi Greg dovrebbe essere in grado di battere gli script in Excel piuttosto rapidamente – LittleBobbyTables

3

Basta eseguire il polling della tabella sys.columns per ogni tabella e creare un sql dinamico ... È una forza bruta ma ti evita di dover scrivere tutto il t-sql.

Ad esempio:

DECLARE @TABLENAME AS VARCHAR(255) 

SET @TABLENAME = 'ReplaceWithYourTableName' 

SELECT 'UPDATE ' + @TableName + ' SET ' + CAST(Name AS VARCHAR(255)) + ' = 99 
WHERE ' + CAST(Name AS VARCHAR(255)) + ' IS NULL' 
FROM sys.columns 
WHERE object_id = OBJECT_ID(@TABLENAME) 
    AND system_type_id = 56 -- int's only 
+0

Sono parzialmente d'accordo con Ashish Patel sull'ISNULL.È necessario eseguire lo scrub dei dati per l'ambiente di report e fornire i valori predefiniti necessari per semplificare l'IMO SQL di reporting. Penso che ISNULL sia una funzione scalare per l'avvio, il che è altrettanto negativo per le prestazioni (non riesco a essere in grado di confermare questa ipotesi tramite ricerche su google :)) Se le colonne non dovrebbero essere NULL, allora forse lo schema dovrebbe essere modificato per non consentire che NULL o un valore predefinito vengano aggiunti a livello di database. Ancora una volta, questo è al di fuori della portata della domanda e probabilmente si riduce agli standard di codifica di ogni negozio. –

4

Dal momento che si deve fare questo tutto il luogo che ho scritto un po 'di javascript per aiutarvi a costruire lo sql. taglia e incolla questo nella barra degli indirizzi del tuo browser per ottenere il tuo sql.

javascript:sql='update your table set ';x=0;while(x <= 40){sql += 'answer_'+x+ ' = coalesce(answer_'+x+',99),\n';x++;};alert(sql); 
2

Non mi piace l'idea di manipolare i dati stessi ai fini della segnalazione. Se si modificano i valori NULL su 99 solo per rendere più semplice la segnalazione, ritengo che i dati siano corrotti. Cosa succede se ci sono altri consumatori oltre alla segnalazione che richiede dati autentici?

Preferisco scrivere una query intelligente per il report. Ad esempio, se si utilizza ISNULL (nome colonna, 99), restituisce 99 ogni volta che il valore della colonna è NULL.

+1

Accetto di solito, ma in questo caso i valori NULL sono stati aggiunti per errore anziché utilizzare il valore corretto di 99. Anche la modifica della query di reporting non è un'opzione in quanto è un sistema di reporting proprietario. –

Problemi correlati