none
Änderung der Datebanktypen RRS feed

  • Frage

  • Hallo zusammen

    Neue Aufgabe, neue Herausforderung…

    Ich habe eine DB welche in der Prod ist. Nur wurde bei der Modellierung der DB die falschen Datentypen gesetzt… Ein Char(1000) welches nur 8 Zeichen eigentlich benötigt ist bisschen falsch formatiert.

    Die Frage die ich jetzt gleich stellen werde ist sicher schon ersichtlich.

    Nur zur Frage, wie soll man das am besten angehen? Ich weiss, dass ich die Datentypen leider nicht einfach so verändern kann. Ich muss jede Tabelle neu erstellen und dann abfüllen. Wie genau soll ich das machen? Die DB hat Stored Procedures und Jobs welche ausgeführt werden.

    Ziel ist es die Datenbanktypen korrekt zu haben und alles rundherum soll immer noch funktionieren. Ich hätte auch ein Testserver mit dem ich dies bearbeiten könnte. Besser als auf der Prod.

    Es ist ein Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (Intel X86)    Enterprise Edition (Build 3790: Service Pack 2)

    Besten Dank für die Mühe im Voraus.

    Montag, 21. Januar 2013 08:55

Antworten

  • Hallo Mehmet,

    das habe ich schon fast befürchtet. Ist aber kein großes Problem. Lass' einfach nach der Umstellung ein UPDATE über die Daten laufen. Hier mal ein Beispiel dafür:

    USE tempdb
    GO
    
    IF OBJECT_ID('dbo.test', 'U') IS NOT NULL
    	DROP TABLE dbo.Test
    	GO
    
    CREATE TABLE dbo.test
    (
    	Id		int			IDENTITY (1, 1) PRIMARY KEY,
    	myname	char(200)	NOT NULL
    );
    
    INSERT INTO dbo.Test (myname)
    VALUES ('Uwe Ricken'),
    ('Beate Ricken'),
    ('Alicia Ricken')
    
    SELECT *, LEN(myname), DATALENGTH(myname)
    FROM dbo.Test
    
    -- Datentypen werden umgestellt
    ALTER TABLE dbo.Test
    ALTER COLUMN myName varchar(200) NOT NULL;
    
    SELECT *, LEN(myname), DATALENGTH(myname)
    FROM dbo.Test
    
    -- Update der Attribute wird durchgeführt
    UPDATE	dbo.Test
    SET		myname = LEFT(myname, LEN(myname))
    
    SELECT *, LEN(myname), DATALENGTH(myname)
    FROM dbo.Test
    
    

    Wichtig ist dabei der Unterschied zwischen LEN und DATALENGTH (wie in er Abfrage gezeigt).
    DATALENGTH() zeigt immer die Länge in Bytes an während LEN() die Anzahl der Zeichen ausgibt (was ja in Deinem Fall gewünscht ist!)

    Uwe Ricken

    MCSA - SQL Server 2012
    MCITP Database Administrator 2005
    MCITP Database Administrator 2008
    MCITP Microsoft SQL Server 2008, Database Development

    db Berater GmbH
    http://www-db-berater.de
    SQL Server Blog (german only)

    • Als Antwort markiert Mehmet.B Freitag, 25. Januar 2013 11:48
    Mittwoch, 23. Januar 2013 16:23

Alle Antworten

  • Hallo Mehmet,

    NEIN - Du musst die Tabellen nicht neu erstellen. Das würde ich auch nicht empfehlen, wenn Du nicht alle Indexe, Foreign Keys, PK, etc. neu erstellen möchtest.

    Um z. B. nur ein Datenfeld zu ändern, kannst Du T-SQL benutzen.

    Beispiel. Varchar(1000) wird zu char(8)

    ALTER TABLE dbo.DeineTabelle
    ALTER COLUMN [DeineSpalte] char(8);

    Achte aber im Vorfeld darauf, ob auch tatsächlich der längste Eintrag 8 Zeichen lang ist!

    SELECT MAX(LEN([DeineSpalte]))
    FROM dbo.DeineTabelle;

    Wie auch immer - Arbeit wird sicherlich genug für Dich da sein!

    Uwe Ricken

    MCITP Database Administrator 2005
    MCITP Database Administrator 2008
    MCITP Microsoft SQL Server 2008, Database Development

    db Berater GmbH
    http://www-db-berater.de
    SQL Server Blog (german only)

    • Als Antwort vorgeschlagen Enrique Martin Montag, 21. Januar 2013 15:46
    Montag, 21. Januar 2013 09:41
  • Hallo Mehmet,
    außerdem würde ich die Version der Datenbank zumindest auf SP2 aktualisieren.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu

    Montag, 21. Januar 2013 12:42
  • Hallo zusammen,

    danke für die gute Erklärung.

    Lieben Gruß

    Tommy

    Montag, 21. Januar 2013 14:57
  • Hallo Uwe

    Besten Dank für den Traid... gerne werde ich mal das anschauen auf einer von 14 Tabellen. Dann kann ich wenigstens mal einen Aufwand schätzen.

    Grüsse

    Mehmet

    Dienstag, 22. Januar 2013 09:28
  • Hallo Mehmet,
    außerdem würde ich die Version der Datenbank zumindest auf SP2 aktualisieren.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu


    Hallo Christoph

    Der Server ist 2008 R2 SP2 schon upgedated worden. Was hätte es für folgen wenn es nicht so wäre?

    Besten Dank für dein Tipp im Voraus.

    Gruss

    Mehmet

    Dienstag, 22. Januar 2013 11:31
  • Hallo Mehmet,
    ich war durch diesen Satz im ersten Posting irritiert:
    Es ist ein Microsoft SQL Server 2008 R2 (RTM)

    Danach stand aber noch was von SP2. Dann ist es ja gut, denn dort sind diverse Sachen gefixed worden.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu

    Dienstag, 22. Januar 2013 13:22
  • Hallo Mehmet,

    NEIN - Du musst die Tabellen nicht neu erstellen. Das würde ich auch nicht empfehlen, wenn Du nicht alle Indexe, Foreign Keys, PK, etc. neu erstellen möchtest.

    Um z. B. nur ein Datenfeld zu ändern, kannst Du T-SQL benutzen.

    Beispiel. Varchar(1000) wird zu char(8)

    ALTER TABLE dbo.DeineTabelle
    ALTER COLUMN [DeineSpalte] char(8);

    Achte aber im Vorfeld darauf, ob auch tatsächlich der längste Eintrag 8 Zeichen lang ist!

    SELECT MAX(LEN([DeineSpalte]))
    FROM dbo.DeineTabelle;

    Wie auch immer - Arbeit wird sicherlich genug für Dich da sein!

    Uwe Ricken

    MCITP Database Administrator 2005
    MCITP Database Administrator 2008
    MCITP Microsoft SQL Server 2008, Database Development

    db Berater GmbH
    http://www-db-berater.de
    SQL Server Blog (german only)

    Hallo UWE

    Ich habe einen weiteren Wunsch. Nun konnte ich die Datentypen ohne weiteres ändern. ist mir noch ein weiteres Problem aufgefallen.
    Wenn ich ein Char(100) zu Varchar(50) ändere habe ich immer noch das Problem, dass das Feld durch das Konventireren von Char zu Varchar die Leerzeichen behaltet. Das heisst, dass ich bei dem Feld "Test......................................." als Inhalt habe.
    Nun stelle ich mir die Frage, wie ich am besten die Leerzeichen rechts vom letzten Charakter löschen kann?

    Grüsse

    Mehmet

    Mittwoch, 23. Januar 2013 15:43
  • Hallo Mehmet,

    das habe ich schon fast befürchtet. Ist aber kein großes Problem. Lass' einfach nach der Umstellung ein UPDATE über die Daten laufen. Hier mal ein Beispiel dafür:

    USE tempdb
    GO
    
    IF OBJECT_ID('dbo.test', 'U') IS NOT NULL
    	DROP TABLE dbo.Test
    	GO
    
    CREATE TABLE dbo.test
    (
    	Id		int			IDENTITY (1, 1) PRIMARY KEY,
    	myname	char(200)	NOT NULL
    );
    
    INSERT INTO dbo.Test (myname)
    VALUES ('Uwe Ricken'),
    ('Beate Ricken'),
    ('Alicia Ricken')
    
    SELECT *, LEN(myname), DATALENGTH(myname)
    FROM dbo.Test
    
    -- Datentypen werden umgestellt
    ALTER TABLE dbo.Test
    ALTER COLUMN myName varchar(200) NOT NULL;
    
    SELECT *, LEN(myname), DATALENGTH(myname)
    FROM dbo.Test
    
    -- Update der Attribute wird durchgeführt
    UPDATE	dbo.Test
    SET		myname = LEFT(myname, LEN(myname))
    
    SELECT *, LEN(myname), DATALENGTH(myname)
    FROM dbo.Test
    
    

    Wichtig ist dabei der Unterschied zwischen LEN und DATALENGTH (wie in er Abfrage gezeigt).
    DATALENGTH() zeigt immer die Länge in Bytes an während LEN() die Anzahl der Zeichen ausgibt (was ja in Deinem Fall gewünscht ist!)

    Uwe Ricken

    MCSA - SQL Server 2012
    MCITP Database Administrator 2005
    MCITP Database Administrator 2008
    MCITP Microsoft SQL Server 2008, Database Development

    db Berater GmbH
    http://www-db-berater.de
    SQL Server Blog (german only)

    • Als Antwort markiert Mehmet.B Freitag, 25. Januar 2013 11:48
    Mittwoch, 23. Januar 2013 16:23
  • Wenn ich ein Char(100) zu Varchar(50) ändere habe ich immer noch das Problem, dass das Feld durch das Konventireren von Char zu Varchar die Leerzeichen behaltet. Das heisst, dass ich bei dem Feld "Test......................................." als Inhalt habe.

    Nun stelle ich mir die Frage, wie ich am besten die Leerzeichen rechts vom letzten Charakter löschen kann?

    hallo Mehmet

    ueberpruef bitte die Option ANSI_PADDING fuer diese Kolumn da dies auch einen unerwuenschten Seiteneffekt haben kann.

    siehe die Beschreibung von SET ANSI_PADDING hier: http://msdn.microsoft.com/de-de/library/ms187403.aspx


    Please use Mark as Answer if my post solved your problem and use Vote As Helpful if a post was useful.

    Mittwoch, 23. Januar 2013 17:44
  • alternativ zu Uwe's Codevorschlag koenntest Du auch RTRIM (T-SQL) benutzen um Leerzeichen am Ende zu entfernen:

    http://msdn.microsoft.com/de-de/library/ms178660%28v=sql.105%29.aspx


    Please use Mark as Answer if my post solved your problem and use Vote As Helpful if a post was useful.


    Mittwoch, 23. Januar 2013 17:47
  • Wenn ich ein Char(100) zu Varchar(50) ändere habe ich immer noch das Problem, dass das Feld durch das Konventireren von Char zu Varchar die Leerzeichen behaltet. Das heisst, dass ich bei dem Feld "Test......................................." als Inhalt habe.

    Nun stelle ich mir die Frage, wie ich am besten die Leerzeichen rechts vom letzten Charakter löschen kann?

    hallo Mehmet

    ueberpruef bitte die Option ANSI_PADDING fuer diese Kolumn da dies auch einen unerwuenschten Seiteneffekt haben kann.

    siehe die Beschreibung von SET ANSI_PADDING hier: http://msdn.microsoft.com/de-de/library/ms187403.aspx


    Please use Mark as Answer if my post solved your problem and use Vote As Helpful if a post was useful.

    Hallo Daniel

    Das ANSI_Padding ist gesetzt, wie im Link von Dir kann ich dies nachvollziehen.
    char(100) Null und Ansi_Padding on... der füllt bei dieser Kombination alles auf.
    Schlecht Datenmoduliert.

    THX für den Beitrag...

    Donnerstag, 24. Januar 2013 08:33
  • alternativ zu Uwe's Codevorschlag koenntest Du auch RTRIM (T-SQL) benutzen um Leerzeichen am Ende zu entfernen:

    http://msdn.microsoft.com/de-de/library/ms178660%28v=sql.105%29.aspx


    Please use Mark as Answer if my post solved your problem and use Vote As Helpful if a post was useful.


    Hallo Daniel,

    Jep das mit dem RTRIM habe ich gesehen. Diese Lösung ist nicht ganz dies was ich möchte. Die Ausgabe kann ich so ändern jep, aber ich möcht die Leerzeichen aus den Daten löschen. Ich habe schon eine DB welche schon Prod ist. Die wurde einfach bisschen falsch aufgesetzt damals.

    Gestern habe ich noch einen anderen Befehl Code gefunden. Einfach ein Update der daten mit Replace

    Update Datenbank
    SET Spalte = Replace(Spalte,' ','');

    So habe ich einfach alle leerzeichen gelöscht. Nur habe ich das nächste Problem auch schon erkannt.
    Wenn ich eine User Tabelle habe welche die Spalte "Nachname" zwei Nachnamen hat, da werde ich wohl auch das Leerzeichen zwischen den Namen löschen, dies will ich auch nicht.

    Aber die Variante ist genau das was mich wirklich glücklich macht.

    Update Datenbank
    SET Spalte = Left(Lager, LEN(Spalte))

    Muss keine Tables erstellen usw.. einfach das was Leer ist weg machen. Man sagt nicht umsonst in der kürze liegt die Würze...

    Donnerstag, 24. Januar 2013 10:50
  • Hallo Mehmet,

    die Lösung von Daniel ist schon o.k. - und sie ist noch kürzer :D
    RTRIM ist vom Prinzip nichts anderes als LEFT(attribute, LEN(attribute))


    Uwe Ricken

    MCSA - SQL Server 2012
    MCITP Database Administrator 2005
    MCITP Database Administrator 2008
    MCITP Microsoft SQL Server 2008, Database Development

    db Berater GmbH
    http://www-db-berater.de
    SQL Server Blog (german only)

    Donnerstag, 24. Januar 2013 11:52
  • Hallo Daniel>

    Jep das mit dem RTRIM habe ich gesehen. Diese Lösung ist nicht ganz dies was ich möchte. Die Ausgabe kann ich so ändern jep, aber ich möcht die Leerzeichen aus den Daten löschen. Ich habe schon eine DB welche schon Prod ist. Die wurde einfach bisschen falsch aufgesetzt damals.

    hallo Mehmet,

    selbstverstaendlich war natuerlich gemeint, dass Du die Spalte in der DB mittels RTRIM updatest und nicht RTRIM beim Select benutzt.


    Please use Mark as Answer if my post solved your problem and use Vote As Helpful if a post was useful.

    Donnerstag, 24. Januar 2013 12:21
  • Hallo Daniel>

    Jep das mit dem RTRIM habe ich gesehen. Diese Lösung ist nicht ganz dies was ich möchte. Die Ausgabe kann ich so ändern jep, aber ich möcht die Leerzeichen aus den Daten löschen. Ich habe schon eine DB welche schon Prod ist. Die wurde einfach bisschen falsch aufgesetzt damals.

    hallo Mehmet,

    selbstverstaendlich war natuerlich gemeint, dass Du die Spalte in der DB mittels RTRIM updatest und nicht RTRIM beim Select benutzt.


    Please use Mark as Answer if my post solved your problem and use Vote As Helpful if a post was useful.

    Hallo Daniel

    Jep habe es jetzt auch versucht mit beiden Syntaxen. Sorry, ich habe es wirklich falsch verstanden. Aber dies ist mir jetzt sicher geblieben         . :-)

    Besten Dank noch mals an Dich und Uwe

    Donnerstag, 24. Januar 2013 12:41