none
Fehlermeldung bei UPDATE RRS feed

  • Frage

  • Hallo zusammen

    mit folgendem Code aktualisiere ich ein Datum von 'Tab1' in 'Tab2'. Tab2 hat ca. 50 Spaltennamen(SMALLDATETIME) wie '64220' , '64355' etc.

    Zuerst deklarierte ich das Datum als SMALLDATETIME. Ich bekomme aber immer diese Fehlermeldung :"Fehler beim Konvertieren einer Zeichenfolge in den smalldatetime-Datentyp." Dann stellte ich um auf varchar.

    Fehlermeldung : UPDATE Tab2 SET 64212 = 10.01.2010 WHERE Kasten = 610
    Falsche Syntax in der Nähe von '64212'.

    CODE:

    USE Test

    DECLARE
        @faw VARCHAR(15),
        @kasten VARCHAR(15),
        @startdatum    VARCHAR(15),
        @col VARCHAR(25),
        @sql VARCHAR(500)

    SET @faw = '64212'
    SET @kasten = '610'
    SET @startdatum = '10.01.2010'

    DECLARE tempcur CURSOR FOR SELECT column_name FROM Information_schema.columns WHERE column_name = @faw

    OPEN tempcur

    FETCH NEXT FROM tempcur INTO @col
    WHILE @@fetch_status = 0

        BEGIN

            SET @sql = 'UPDATE Tab2 SET ' + @col + ' = ' + @Startdatum + ' WHERE Kasten = ' + @Kasten + ''

            PRINT @sql
            EXEC (@sql)
            FETCH NEXT FROM tempcur INTO @col

        END

    CLOSE tempcur
    DEALLOCATE tempcur

     

    ich arbeite mit mssql 2005

    Kann mir jemand helfen. Danke.

    Buarli

    Samstag, 21. August 2010 13:23

Antworten

  • Hallo Buarli,

    zunächst zum Fehler:
    Bezeichner , die nicht mit einem Buchstaben beginnen, müssen in Begrenzer eingeschlossen werden,
    was man bei dynamischen SQL am besten immer macht und dafür QUOTENAME verwendet.

    Das zweite Problem wäre die Verwendung von Datumsangeaben in SQL in Zeichenfolgen,
    siehe dazu http://www.insidesql.org/blogs/frankkalis/2010/08/19/der-ultimative-guide-fuer-die-datetime-datentypen

    und auch eine Zeichenkette muß korrekt in Anführungszeichen eingeschlossen werden
    (wenn Kasten wirklich ein VARCHAR ist).

    In dem man anstatt EXEC sp_executesql verwendet, hat man zudem weniger Probleme
    mit solchen Verkettungen.

    Nicht zuletzt ist die Abfrage auf die Spalten so wie Du sie jetzt hast, nicht sonderlich sinnvoll.
    Da käme immer nur eine Spalte (die in @faw) und das ggf. über alle Tabellen.
    Ich habe das unten mal PI * Daumen angepasst...
    Aber ob es genau das ist, was Du willst, kann ich nicht sagen.
    Schau es Dir erst mal an und poste ggf. die Tabellenbeschreibung.

    DECLARE
      @faw VARCHAR(15),
      @kasten VARCHAR(15),
      @startdatum smalldatetime,
      @col sysname,
      @sql NVARCHAR(500)
    
    SET @faw = '64212'
    SET @kasten = '610'
    SET @startdatum = '20100101'
    
    DECLARE tempcur CURSOR FOR 
    	SELECT column_name 
    	FROM INFORMATION_SCHEMA.COLUMNS 
    	WHERE 
    		-- gibt so keinen Sinn da nur eine Spalte geliefert werden würde
    		-- COLUMN_NAME = @faw
    		-- auf die Tabelle begrenzen
    		TABLE_NAME = N'Tab2'
    		-- alle Spalten mit Datentyp smalldatetime
    		AND DATA_TYPE = 'smalldatetime'
    
    OPEN tempcur
    FETCH NEXT FROM tempcur INTO @col
    WHILE @@fetch_status = 0
    BEGIN
    
      SET @sql = 'UPDATE Tab2 SET ' + QUOTENAME(@col) + ' = @Startdatum WHERE Kasten = @Kasten';
    
      PRINT @sql
      EXEC sp_executesql @sql, 
    		N'@Startdatum datetime, @Kasten varchar(15)',
    		@startdatum, @kasten
    
      FETCH NEXT FROM tempcur INTO @col
    END
    
    CLOSE tempcur
    DEALLOCATE tempcur
    
    Gruß Elmar

     

     

     

    Samstag, 21. August 2010 15:05

Alle Antworten

  • Hallo Buarli,

    zunächst zum Fehler:
    Bezeichner , die nicht mit einem Buchstaben beginnen, müssen in Begrenzer eingeschlossen werden,
    was man bei dynamischen SQL am besten immer macht und dafür QUOTENAME verwendet.

    Das zweite Problem wäre die Verwendung von Datumsangeaben in SQL in Zeichenfolgen,
    siehe dazu http://www.insidesql.org/blogs/frankkalis/2010/08/19/der-ultimative-guide-fuer-die-datetime-datentypen

    und auch eine Zeichenkette muß korrekt in Anführungszeichen eingeschlossen werden
    (wenn Kasten wirklich ein VARCHAR ist).

    In dem man anstatt EXEC sp_executesql verwendet, hat man zudem weniger Probleme
    mit solchen Verkettungen.

    Nicht zuletzt ist die Abfrage auf die Spalten so wie Du sie jetzt hast, nicht sonderlich sinnvoll.
    Da käme immer nur eine Spalte (die in @faw) und das ggf. über alle Tabellen.
    Ich habe das unten mal PI * Daumen angepasst...
    Aber ob es genau das ist, was Du willst, kann ich nicht sagen.
    Schau es Dir erst mal an und poste ggf. die Tabellenbeschreibung.

    DECLARE
      @faw VARCHAR(15),
      @kasten VARCHAR(15),
      @startdatum smalldatetime,
      @col sysname,
      @sql NVARCHAR(500)
    
    SET @faw = '64212'
    SET @kasten = '610'
    SET @startdatum = '20100101'
    
    DECLARE tempcur CURSOR FOR 
    	SELECT column_name 
    	FROM INFORMATION_SCHEMA.COLUMNS 
    	WHERE 
    		-- gibt so keinen Sinn da nur eine Spalte geliefert werden würde
    		-- COLUMN_NAME = @faw
    		-- auf die Tabelle begrenzen
    		TABLE_NAME = N'Tab2'
    		-- alle Spalten mit Datentyp smalldatetime
    		AND DATA_TYPE = 'smalldatetime'
    
    OPEN tempcur
    FETCH NEXT FROM tempcur INTO @col
    WHILE @@fetch_status = 0
    BEGIN
    
      SET @sql = 'UPDATE Tab2 SET ' + QUOTENAME(@col) + ' = @Startdatum WHERE Kasten = @Kasten';
    
      PRINT @sql
      EXEC sp_executesql @sql, 
    		N'@Startdatum datetime, @Kasten varchar(15)',
    		@startdatum, @kasten
    
      FETCH NEXT FROM tempcur INTO @col
    END
    
    CLOSE tempcur
    DEALLOCATE tempcur
    
    Gruß Elmar

     

     

     

    Samstag, 21. August 2010 15:05
  • Hallo Elmar

    vielen Dank, alles klappt wunderbar. Ich bin noch blutiger Anfänger und froh über jede Info.

    In Bezug auf die Select-Klausel: Ich binde diesen Code in einen übergeordneten Cursor ein, der mir zeilenweise neue Daten liefert.

    Darum nur ein Datum.

     

    Nochmals vielen Dank

    Gruss Buarli
    Samstag, 21. August 2010 16:03