2013-09-27 6 views
5

Ho una tabella SQL con un numero elevato di colonne. Per qualche motivo, alcune colonne hanno celle vuote invece di celle NULL. Vorrei trasformare tutte le celle vuote in tutte le colonne in NULL.Sostituisci celle vuote con valori NULL in un numero elevato di colonne

So che la strada da percorrere per una singola colonna è:

UPDATE your_table SET column = NULL WHERE column = '' 

Tuttavia, io non sono sicuro di come eseguire una logica simile in modo efficiente per tutte le colonne senza dover scrivere i nomi delle colonne uno per uno .

Grazie,

+1

Potrebbe volerci più tempo per capire un modo intelligente di farlo che aggiornare ogni colonna manualmente. In effetti, sono passati 17 minuti da quando hai fatto la domanda. È possibile che tu possa essere già stato fatto. –

+1

@DanBracuk che divertimento è? Imparare a farlo in modo efficiente ora potrebbe salvare un numero incalcolabile di minuti lungo la strada. –

risposta

18

eseguire la seguente query:

SELECT 'UPDATE yourtable SET ' + name + ' = NULL WHERE ' + name + ' = '''';' 
FROM syscolumns 
WHERE id = object_id('yourtable') 
    AND isnullable = 1; 

L'output di questa query sarà un blocco di script SQL come questo:

UPDATE yourtable SET column1 = NULL WHERE column1 = ''; 
UPDATE yourtable SET column2 = NULL WHERE column2 = ''; 
UPDATE yourtable SET column3 = NULL WHERE column3 = ''; 
-- etc... 

Copia e incolla lo script SQL in una nuova query ed eseguilo per aggiornare tutte le colonne.

+0

Questo è un trucco eccellente! Grazie! Ma esiste un modo per passare i risultati della prima query a qualcosa che posso eseguire automaticamente? Lo sto facendo tramite C#, ecco perché ... Grazie! – Mayou

+0

Dipende da come stai facendo il tuo accesso db, ma dici che stai usando C# e Linq To SQL, puoi fare qualcosa di simile: 'using (MyDataContext db = new MyDataContext()) { string queryBuilder =". ..prima domanda da sopra ... "; var resultsetOfUpdateQueries = db.ExecuteQuery (queryBuilder); foreach (stringa oneUpdateQuery in resultsetOfUpdateQueries) { db.ExecuteCommand (oneUpdateQuery); } } Nessun problema relativo all'iniezione SQL poiché i soli componenti variabili dell'istruzione SQL dinamica saranno tutti nomi di colonne da una tabella di dizionario. –

+0

Perché dovresti farlo, presumibilmente un compito fuori, in C#? – podiluska

3

si potrebbe fare una query su syscolumns per ottenere un elenco di colonne, e utilizzare i risultati per costruire la query.

select quotename(name) + ' = nullif (' + quotename(name)+ ','''')' 
from syscolumns 
where id = object_id('yourtable') 

Inoltre, se si scrive la query come

update yourtable 
set 
    yourcolumn=nullif(yourcolumn, ''), 
    yourcolumn2=nullif(yourcolumn2, ''), 
    ...  

allora si può fare in una singola query senza una clausola where

+0

Dovrei ancora scrivere ogni colonna per controllare 'nullif'. Non sarebbe molto efficiente. – Mayou

+0

Grazie. Ricevo la prima parte, ma non sono sicuro di come utilizzare il risultato della prima query per scrivere la seconda: ovvero come passare i nomi delle colonne ottenuti dalla prima query alla seconda query – Mayou

+1

@Mariam Il modo semplice è quello di copia i risultati e incollali in una nuova query. – podiluska

2

In realtà uso la risposta di Robert N sopra ogni giorno quando sto importando insiemi di dati di file flat, quindi l'ho inserito in una stored procedure a cui potrei passare un nome di tabella. Compila semplicemente una tabella temporanea con le istruzioni di aggiornamento, quindi esegue ogni riga nella tabella.

USE [master] 
    GO 
    SET ANSI_NULLS ON 
    GO 
    SET QUOTED_IDENTIFIER ON 
    GO 
    -- ============================================= 
    -- Author:  LikeableBias 
    -- Create date: 2016-06-27 
    -- Description: Finds and NULLs all blank values in table where column allows nulls 
    -- ============================================= 
    CREATE PROCEDURE [dbo].[sproc_NullBlanks] 
     @tablename NVARCHAR(MAX) 
    AS 
    BEGIN 
     SET NOCOUNT ON; 
    --------Insert update statements to temp table for execution 
    DECLARE @statements TABLE (statement NVARCHAR(MAX)) 
    INSERT INTO @statements 
      (statement) 
     SELECT ('UPDATE '[email protected]+' SET [' + name + '] = NULL WHERE ' + name + ' = '''';') 
     FROM syscolumns 
     WHERE id = OBJECT_ID(@tablename) 
     AND isnullable = 1; 
    --------Open cursor, execute statements, then close cursor 
    DECLARE @statement NVARCHAR(MAX) 
    DECLARE cur CURSOR LOCAL FOR 
     SELECT statement FROM @statements 
    OPEN cur 
    FETCH NEXT FROM cur INTO @statement 
    WHILE @@FETCH_STATUS = 0 BEGIN 
     EXEC sys.sp_executesql @statement 
     FETCH NEXT FROM cur INTO @statement 
    END 
    CLOSE cur 
    DEALLOCATE cur 

    END 
    GO