none
Update meineTabelle set Datenfeld = 0 where Datenfeld IS NULL RRS feed

  • Frage

  • Hallo zusammen,

     

    auf einem SQL2008 Version 10.0.2531.0 muß ich in einer Tabelle ca. 80 Felder updaten. Wenn Datenfeld1 = null soll eine 0 rein. Das ganze dann für ca. 80 Felder.

     

    Update meineTabelle set Datenfeld1 = 0 where Datenfeld1 IS NULL

    Update meineTabelle set Datenfeld2 = 0 where Datenfeld2 IS NULL

     

    Geht das evtl. auch in einem Query? Kann mir dabei jemand helfen?

     

    Vielen Dank schon im voraus.

     

    Servus

    Winfried

    Montag, 2. August 2010 12:00

Antworten

  • Hallo Winfried,

    sicher:

    UPDATE MeineTabelle SET 
    	-- via CASE
    	DatenFeld1 = CASE WHEN DatenFeld1 IS NULL THEN 0 ELSE DatenFeld1 END,
    	-- Via ISNULL / COALESCE
    	DatenFeld2 = ISNULL(DatenFeld2, 0)
    -- Wenn es nicht ohnehin fast alle sind:
    WHERE DatenFeld1 IS NULL OR DatenFeld2 IS NULL
    
    
    Gruß Elmar

    Montag, 2. August 2010 12:08

Alle Antworten

  • Hallo Winfried,

    sicher:

    UPDATE MeineTabelle SET 
    	-- via CASE
    	DatenFeld1 = CASE WHEN DatenFeld1 IS NULL THEN 0 ELSE DatenFeld1 END,
    	-- Via ISNULL / COALESCE
    	DatenFeld2 = ISNULL(DatenFeld2, 0)
    -- Wenn es nicht ohnehin fast alle sind:
    WHERE DatenFeld1 IS NULL OR DatenFeld2 IS NULL
    
    
    Gruß Elmar

    Montag, 2. August 2010 12:08
  • UPDATE MeineTabelle SET 
    
    	-- via CASE
    
    	DatenFeld1 = CASE WHEN DatenFeld1 IS NULL THEN 0 ELSE DatenFeld1 END,
    
    	-- Via ISNULL / COALESCE
    
    	DatenFeld2 = ISNULL(DatenFeld2, 0)
    
    -- Wenn es nicht ohnehin fast alle sind:
    
    WHERE DatenFeld1 IS NULL OR DatenFeld2 IS NULL
    


    Danke. ;-)

     

    Servus

    Winfried

    Montag, 2. August 2010 13:33
  • Auch wenn Elmar die Antwort schon gegeben hat:

    Du könntest über die Columns laufen und mit dyn. Sql arbeiten. Das könnte u.U. schneller laufen, ja nach Datenmenge.

    Außerdem erspart man sich eine Menge Tip-Arbeit ;-))

    Beispiel:

    use Adventureworks

    declare @column varchar(100)

    declare @sql varchar(2000)

    declare mycur cursor for select column_name from Information_schema.columns where table_name = 'Employees'

    open mycur

    fetch next from mycur into @column

    while @@fetch_status = 0

    begin

    set @sql = 'update mytable set ' + @column + ' = 0 where ' + @column + ' is null'

    print @sql   -- for evaluation

    exec (@sql)

    fetch next from mycur into @column

    end

    close mycur

    deallocate mycur

    Montag, 2. August 2010 19:06
  • Am 02.08.2010 schrieb Christa Kurschat:

    Auch wenn Elmar die Antwort schon gegeben hat:

    Du könntest über die Columns laufen und mit dyn. Sql arbeiten. Das könnte u.U. schneller laufen, ja nach Datenmenge.

    Außerdem erspart man sich eine Menge Tip-Arbeit ;-))

    Für sparen beim tippen bin ich immer zu haben. ;)

    Beispiel:

    Danke für das Beispiel. Da das noch alles Neuland für mich ist, werde
    ich das gerne testen und fragen was ich nicht verstehe.

    Servus
    Winfried


    Connect2WSUS: http://www.grurili.de/tools/Connect2WSUS.exe
    GPO's: http://www.gruppenrichtlinien.de
    Community Forums NNTP Bridge: http://communitybridge.codeplex.com/

    Montag, 2. August 2010 21:00
  • use Adventureworks

    declare @column varchar(100)

    declare @sql varchar(2000)

    declare mycur cursor for select column_name from Information_schema.columns where table_name = 'Employees'

    open mycur

    fetch next from mycur into @column

    while @@fetch_status = 0

    begin

    set @sql = 'update mytable set ' + @column + ' = 0 where ' + @column + ' is null'

    print @sql   -- for evaluation

    exec (@sql)

    fetch next from mycur into @column

    end

    close mycur

    deallocate mycur

    Funktioniert das mit VIEWs nicht? Mein naiver Versuch:

     

    use Test
    
    declare @column varchar(100)
    
    declare @sql varchar(2000)
    
    declare mycur cursor for select column_name from Information_schema.columns where View_NAME = 'MeineView' 
    
    open mycur
    
    fetch next from mycur into @column
    
    while @@fetch_status = 0
    
    begin
    
    set @sql = 'update 'MeineView' set ' + @column + ' = 0 where ' + @column + ' is null'
    
    print @sql  -- for evaluation
    
    exec (@sql)
    
    fetch next from mycur into @column
    
    end
    
    close mycur
    
    deallocate mycur
    
    

    Fehlermeldung:

    Meldung 207, Ebene 16, Status 1, Zeile 7

    Ungltiger Spaltenname 'View_NAME'.

     

    Die View gibt es selbstverständlich. Dort sind nur die Felder enthalten, die NULL sein können.

    Vielen Dank schon im voraus.

     

    Servus

    Winfried

    Dienstag, 3. August 2010 09:35
  • Hallo Winfried,

    ob Tabelle oder Sicht, die Spalte heißt immer TABLE_NAME, siehe INFORMATION_SCHEMA.COLUMNS

    Ein etwas aufgebohrtes Skript, als Beispiel hier die Northwind.Products:

    USE Northwind;
    GO
    
    DECLARE @schema_name sysname, @table_name sysname;
    
    -- Northwind Products
    SELECT @schema_name = N'dbo', @table_name = 'Products'
    
    -- Cursor für Update und Where
    DECLARE QueryCursor CURSOR 
    FOR SELECT Sql.*
    FROM (SELECT QUOTENAME(COLUMN_NAME),
    		-- Default Wert basteln...
    		CASE WHEN DATA_TYPE IN ('char', 'nchar', 'varchar', 'nvarchar') THEN ''''''
    		-- TODO: Weitere Datentypen
    		ELSE '0' END
    	FROM INFORMATION_SCHEMA.COLUMNS
    	WHERE TABLE_SCHEMA = @schema_name 
    		AND TABLE_NAME = @table_name
    	ORDER BY ORDINAL_POSITION) AS Columns(ColumnName, DefaultValue)
    CROSS APPLY (SELECT
    	ColumnName + N' = ISNULL(' + ColumnName + N', ' + DefaultValue + N')', 
    	ColumnName + N' IS NULL' ) AS Sql(UpdatePart, WherePart)
    
    DECLARE @UpdatePart nvarchar(1024), 
    		@WherePart nvarchar(1024);
    DECLARE @updatesql nvarchar(MAX) = N'';
    DECLARE @wheresql nvarchar(MAX) = N'';
    DECLARE @crlf nchar(2) = NCHAR(13) + NCHAR(10);
    	
    OPEN QueryCursor
    FETCH QueryCursor INTO @UpdatePart, @WherePart;
    WHILE @@FETCH_STATUS = 0
    BEGIN
    	IF @updatesql <> N'' 
    		SET @updatesql += N', ' + @crlf;
    	SET @updatesql += @UpdatePart;
    	
    	IF @wheresql <> N''
    		SET @wheresql += @crlf + N'  OR ';
    	SET @wheresql += @WherePart;
    	
    	FETCH QueryCursor INTO @UpdatePart, @WherePart;
    END
    CLOSE QueryCursor
    DEALLOCATE QueryCursor
    
    DECLARE @sql nvarchar(MAX)
    SET @sql = N'UPDATE ' 
    	+ QUOTENAME(@schema_name) + N'.' + QUOTENAME(@table_name) 
    	+ @crlf + N'SET ' + @crlf
    	+ @updatesql
    	+ @crlf + N' WHERE ' + @wheresql + N';';
    	
    PRINT @sql;
    	
    
    Ich nutze dort einige Dinge aus SQL Server 2005/2008 wie CROSS APPLY etc.
    Den Standardwert bilde ich über den Datentyp, allerdings habe ich nicht
    alle Datentypen abgebildet - ggf. noch nachrüsten.

    Ebenso habe ich das sofortige Ausführen verzichtet,
    besser ist i. a.  man schaut sich das ganze vorher noch mal an ;-)

    Gruß Elmar

     

    Dienstag, 3. August 2010 10:19
  • ob Tabelle oder Sicht, die Spalte heißt immer TABLE_NAME, siehe INFORMATION_SCHEMA.COLUMNS

    Woher kann ich aus dem o.g.Artikel ableiten, dass es bei Sichten mit dem TABLE_NAME funktioniert?

     

    Vielen Dank auch für das Script. Das muß ich mir in aller Ruhe zu Gemüte führen. ;)

     

    Servus

    Winfried

    Dienstag, 3. August 2010 11:36
  • Hallo Winfried,

    Die Information Schema Sichten basieren auf den ANSI-SQL Schemata (inkl. der Großschreibung).
    (und werden in der SQL Server Dokumentation eher stiefmütterlich dokumentiert).
    Dort werden Sichten als virtuelle Tabellen angesehen.
    Die Spaltennamen orientieren sich deswegen an

    Wonach die Sichten wiederum in INFORMATION_SCHEMA.VIEWS aufgeführt werden.

    Eine vollständige Verknüpfung wäre:

    SELECT * 
    FROM INFORMATION_SCHEMA.VIEWS
    INNER JOIN INFORMATION_SCHEMA.COLUMNS	
    	ON VIEWS.TABLE_CATALOG = COLUMNS.TABLE_CATALOG
    	AND VIEWS.TABLE_SCHEMA = COLUMNS.TABLE_SCHEMA
    	AND VIEWS.TABLE_NAME = COLUMNS.TABLE_NAME
    	
    
    wobei man beim SQL Server TABLE_CATALOG weglassen könnte,
    da diese Sichten auf die aktuelle Datenbank zugreifen.

    Alternativ kannst Du auch die SQL Server eigenen Katalogsichten verwenden,
    das wäre dann sys.views und sys.columns (ab SQL Server 2005), z. B.:

    SELECT * 
    FROM sys.views
    INNER JOIN sys.columns
    	ON views.object_id = columns.object_id
    
    

    Wie Du siehst ist dort einiges mehr enthalten und einiges wiederum mühsamer zu extrahieren
    (für oben z. B. der Datentyp).
    Die Information Schema Sichten haben als ANSI normiert den Vorteil, langfristig stabiler zu sein
    (sie gibt es seit SQL Server 7) und die wesentlichen Informationen sind dort auch enthalten.

    Gruß Elmar

    Dienstag, 3. August 2010 13:30
  • Am 03.08.2010 schrieb Elmar Boye [MVP]:

    Die Information Schema Sichten basieren auf den ANSI-SQL Schemata (inkl. der Großschreibung).
    (und werden in der SQL Server Dokumentation eher stiefmütterlich dokumentiert).
    Dort werden Sichten als virtuelle Tabellen angesehen.
    Die Spaltennamen orientieren sich deswegen an

    Wonach die Sichten wiederum in INFORMATION_SCHEMA.VIEWS <http://msdn.microsoft.com/de-de/library/ms181381.aspx> aufgeführt werden.

    Vielen Dank für Deine Erklärung. Ich glaub langsam lichtet sich der
    Nebel. ;)

    Servus
    Winfried


    Connect2WSUS: http://www.grurili.de/tools/Connect2WSUS.exe
    GPO's: http://www.gruppenrichtlinien.de
    Community Forums NNTP Bridge: http://communitybridge.codeplex.com/

    Dienstag, 3. August 2010 17:29