Datenbanken und mehr

17. September 2007

Typofehler in text Feldern

Filed under: T-SQL — Urs Gehrig @ 15:56

Heute wurde ich um einen Tipp gebeten: Wie korrigiere ich einen Tippfehler in meinen Daten?

Eigentlich mit REPLACE() ganz einfach, wenn da nicht noch die Randbedingungen wären J. Einerseits läuft die DB noch immer auf einem SQL Server 2000 (wie so viele andere ja auch) und anderseits sind die Daten in einem Feld vom Typ text abgelegt. Und da haben wir auch schon den Schlamassel; REPLACE() lässt sich nicht auf Felder vom Typ text anwenden L. Glück gehabt: Es gibt eine Einschränkung in den Daten, welche die ganze Sache wieder vereinfacht: Das falsch geschriebene Wort kommt immer in den ersten 8000 Zeichen vor.

Die korrekte Fragestellung lautet also: Wie korrigiere ich einen Tippfehler in den ersten 8000 Zeichen meiner Daten vom Typ text? Und das ist ganz klar ein Fall für UPDATETEXT:

BEGIN TRAN

DECLARE @wrongWord varchar(50)
DECLARE @correctWord varchar(50)
SELECT  @wrongWord = ‚generalinvoicerequest_410.xsd‘, @correctWord = ‚generalInvoiceRequest.xsd‘ –- use camel-case

DECLARE @ptrval binary(16)
DECLARE @offset int
DECLARE @length int
DECLARE myCursor CURSOR FAST_FORWARD READ_ONLY FOR
    SELECT TEXTPTR(message_data), CHARINDEX(@wrongWord, SUBSTRING(message_data,1,8000)) 1, LEN(@wrongWord)
   
FROM IO_XMLOutput
    WHERE Identifier IN (SELECT f.hnnummer
                         FROM fall f

                              JOIN auftrag a ON a.id = f.auftrag_id AND a.nr IN (‚2007.00001‘, ‚2007.00004‘, ‚2007.00006‘)
                              
JOIN leistungserbringer le ON le.id = f.leistungserbringer_id AND le.nr = 999007
                              JOIN kostentraeger_patient kp ON kp.id = f.Kostentraeger_Patient_Id
                             
JOIN kostentraeger kt ON kt.id = kp.Kostentraeger_Id
                        
WHERE f.patienttiers = 2
                             
AND kt.kassencode IN (11110, 11103))
OPEN myCURSOR
FETCH NEXT FROM myCursor INTO @ptrval, @offset, @length
WHILE @@FETCH_STATUS = 0
BEGIN
   
UPDATETEXT IO_XMLOutput.message_data
              
@ptrval — textpointer
              
@offset — insert offset
              
@length — delete length
              
@correctWord — new value
    FETCH NEXT FROM myCursor INTO @ptrval, @offset, @length
END
CLOSE myCursor
DEALLOCATE myCursor

COMMIT

Ganz schön kompliziert, oder? Sicher ein Grund mehr auf SQL Server 2005 zu migrieren. Denn neu gibt es ja den Datentyp varchar(max); und da funktioniert auch REPLACE() wieder. Mehr darüber findest du in meinem Blogbeitrag Wie lade ich Dokumente in die DB?

Advertisements

2 Kommentare »

  1. hallo urs

    das problem liegt eigentlich nur bei „charindex“ dieser kann text und ntext nicht verabeiten. nimmt man dagegen „patindex“ funktioniert es auch mit text > 8000 zeichen.
    gruss, giusi

    —————————————————–

    DECLARE @ptrval binary(16)
    DECLARE @pos int
    DEClARE @len INT
    DELCARE @substring NVARCHAR

    select
    @len = LEN(‚text_to_be_replaced‘),
    @Ptrval = textptr(replace_textfield),
    @pos = PATINDEX(‚%text_to_be_replaced%‘, replace_textfield)-1
    from
    test_table
    where
    bla bla

    –SELECT @ptrval, @pos, @len

    UPDATETEXT test_table.replace_textfield @ptrval @pos @len ’new_text‘

    Kommentar von gesharptes — 18. September 2007 @ 08:30

  2. Hallo Giusi,

    Danke für deinen Tipp; da hast du natürlich recht. CHARINDEX() war nicht gerade so ne leuchtende Idee von mir. Das eigentliche Problem liegt ja aber viel mehr in der Notwendigkeit, das Text Feld mit einem Loop und UPDATETEXT aktualisieren zu müssen. Mit varchar(max) entfällt der Loop und anstelle von UPDATETEXT kann ich REPLACE() benutzen. Das macht es wirklich einfach.

    Gruss, Urs

    Kommentar von Urs Gehrig — 18. September 2007 @ 13:13


RSS feed for comments on this post. TrackBack URI

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

Bloggen auf WordPress.com.

%d Bloggern gefällt das: