SQL Update - Text austauschen

Thema wurde von Anonymous, 6. Februar 2024 erstellt.

  1. Anonymous

    Anonymous Erfahrener Benutzer

    Registriert seit:
    18. August 2021
    Beiträge:
    653
    Danke erhalten:
    88
    Danke vergeben:
    266
    #1 Anonymous, 6. Februar 2024
    Zuletzt bearbeitet: 6. Februar 2024
    Hallo,

    ich scheitere an folgende SQL-Aufgabe.

    Es steht, nur als Beispiel, folgender zusammenhängender Fantasie-Text in der Tabelle: products_description - Spalte products_description:

    Code:
    <h2>Das ist eine h2 Überschrift mit dem Wort Hallo in der Farbe grün geschrieben</h2>
    
    <h3>Die Farbe grün ist eine schöne Farbe</h3>
    
    <p>Allerdings ist die Farbe grün auch sehr schön.</p>
    
    <p>Insgesamt kann man sagen, dass beide Farben, blau und grün, sehr schöne Farben sind</p>
    
    
    Ich möchte nun das Wort "grün" im p-Element: <p>Allerdings ist die Farbe grün auch sehr schön.</p>

    in das Wort blau ändern, sodass der Satz dann heißt:

    <p>Allerdings ist die Farbe blau auch sehr schön.</p>

    Das würde ich gerne mit einem UPDATE Befehl machen. Die Schwierigkeit ist hierbei, dass der komplette Text in der Spalte products_description steht. Würde man nachtehende Anweisung nehmen, würde jedes Wort grün in blau geändert. was ich natürlich nicht will.

    Funktioniert also nicht mit:

    UPDATE products_description SET products_description = REPLACE(products_description,'grün','blau')
    WHERE ... ;

    Es soll ja nur an der bestimmten Stelle das Wort grün in blau getauscht werden.


    Es gibt noch eine Hürde:

    Der zu ändernde Satz <p>Allerdings ist die Farbe grün auch sehr schön.</p> kann sich textlich unterscheiden, da er sehr häufig in der DB variierend vorkommt. Die Textstelle kann also in vielen Varianten vorkommen, aber immer mit dem Wort grün in diesem p-Element, welches dann in blau geändert werden soll.

    Wäre der Text immer derselbe, wäre es machbar zum Beispiel mit:

    UPDATE products_description SET products_description = REPLACE(products_description,'Allerdings ist die Farbe grün','Allerdings ist die Farbe blau')
    WHERE ... ;
     
  2. WinHelp GmbH

    WinHelp GmbH Erfahrener Benutzer

    Registriert seit:
    2. April 2019
    Beiträge:
    79
    Danke erhalten:
    26
    Danke vergeben:
    20
    Servus @UuSK ,

    da braucht es schon ein wenig mehr Information was mit "Es soll ja nur an der bestimmten Stelle das Wort grün in blau getauscht werden." das ist nicht sonderlich spezifisch, was es unmöglich macht hierzu etwas zu sagen.

    Soll es immer das erste Vorkommen sein? Dann wäre etwas in diese Richtung vermutlich möglich:
    Code:
    UPDATE products_description
    SET products_description = CONCAT(REPLACE(LEFT(products_description, INSTR(products_description, 'grün')), 'grün', 'blau'), SUBSTRING(products_description, INSTR(products_description, 'grün') + 1));
    Bei Google gibt's da mehrere Treffer unter dem Suchbegriff "mysql replace only first occurrence". Unter den Top5 auch Erklärungen warum und wie das funktioniert.

    Falls es nicht immer der erste Treffer sein soll, wird es schon schwieriger. Da wäre meine Empfehlung die Daten per CSV Exportieren dann von Hand oder über OpenAI aufbereiten lassen. Wichtig: Beim Export darauf achten das die products_id angegeben ist. Über Excel kann man sich für jedes einzelne Produkt einen Update bauen, welche man dann auf der DB ausführen kann.
     
  3. Anonymous

    Anonymous Erfahrener Benutzer

    Registriert seit:
    18. August 2021
    Beiträge:
    653
    Danke erhalten:
    88
    Danke vergeben:
    266
    @WinHelp GmbH - Danke.

    Nun, die Änderung soll immer im ersten Paragraphen stattfinden.
    (<p>Allerdings ist die Farbe grün auch sehr schön.</p>)

    Nein, grün kommt im Text davor und auch danach vor, siehe Beispiel oben.

    Das zu ändernde <p>-Element zu lokalisieren ist nicht schwer. Das erste Erkennungsmerkmal ist "</h3>_<p>".

    Das letzte Erkennungsmerkmal ist "</p>_<p>".

    Wenn das Wort grün in einem beliebig formulierten Satz zwischen diesen beiden Merkmalen vorkommt, soll es in blau geändert werden.

    Also, zum Beispiel:

    </h3>
    <p>
    Mein Kugelschreiber schreibt in der Farbe grün.
    </p>
    <p>

    Dann soll grün durch blau ersetzt werden.

    Ich hatte schon einiges probiert, hatte auch mit Platzhalter gespielt, funktioniert aber nicht.

    Probiert in etwa so:

    UPDATE products_description SET products_description = REPLACE(products_description,'%</h3>_<p>%grün%</p>_<p>%','%</h3>_<p>%blau%</p>_<p>%') WHERE ... ;


    Es bliebe, so fürchte ich, nur die Möglichkeit über ein kleines php-Script.

    Im Script via SQL Anweisungen das Feld auslesen, und dann den String zwischen </h3><p> und </p><p> manipulieren und zurücklesen.

    Gruß

    Bernd
     
  4. Anonymous

    Anonymous Erfahrener Benutzer

    Registriert seit:
    17. Oktober 2018
    Beiträge:
    140
    Danke erhalten:
    78
    Danke vergeben:
    18
    #4 Anonymous, 7. Februar 2024
    Zuletzt bearbeitet: 7. Februar 2024
    @UuSK Das war doch schon ganz gut überlegt. Man muss noch etwas tiefer in die Trickkiste, zu den Regulären Ausdrücken greifen.
    Code:
    -- MySQL (ungetestet):
    UPDATE `products_description` SET `products_description` = REGEXP_REPLACE(`products_description`, '(?<=<\/h3><p>)(.*?)(grün)(.*?)(?=<\/p>)', '$1blau$3');
    -- MariaDB (getestet):
    UPDATE `products_description` SET `products_description` = REGEXP_REPLACE(`products_description`, '(?<=<\/h3><p>)(.*?)(grün)(.*?)(?=<\/p>)', '\\1blau\\3');
    
    kurze Erklärung in einfacher Sprache:
    2. Es wird im Text nach "grün" gesucht mit irgendwelchen Zeichen davor und irgendwelchen Zeichen dahinter. (.*?)(grün)(.*?)
    1. Es wird geschaut, ob/wo vor "irgendwelchen Zeichen davor" die Zeichenkette "</h3><p>" steht. (?<=<\/h3><p>)
    3. Es wird geschaut, ob/wo nach "irgendwelchen Zeichen dahinter" die Zeichenkette "</p>" steht. (?=<\/p>)
    Wenn alle drei Bedingungen erfüllt sind, ist es ein Treffer und es gibt drei Gruppen 1: die Zeichen davor (beginnend nach den Tags) 2: "grün" 3: die Zeichen danach (bis vor dem Tag </p>). Der Treffer wird ersetzt durch 1-"blau"-3

    Es gibt Unterschiede in der Syntax bei REGEXP_REPLACE zwischen MySQL und MariaDB!

    https://regexr.com/ und https://dbfiddle.uk/ ist Dein Freund bei solchen Geschichten.

    Vielleicht geht's auch simpler.
     
  5. WinHelp GmbH

    WinHelp GmbH Erfahrener Benutzer

    Registriert seit:
    2. April 2019
    Beiträge:
    79
    Danke erhalten:
    26
    Danke vergeben:
    20
    @UuSK die Lösung von @Pepe sollte zum ziel führen. Das ist sehr treffend.
     
  6. Anonymous

    Anonymous Erfahrener Benutzer

    Registriert seit:
    18. August 2021
    Beiträge:
    653
    Danke erhalten:
    88
    Danke vergeben:
    266
    #6 Anonymous, 7. Februar 2024
    Zuletzt bearbeitet: 7. Februar 2024
    @WinHelp GmbH - @Pepe, vielen Dank für Eure Unterstützung.

    Ich werde das umsetzen.

    Vielen vielen Dank nochmals!

    Gruß

    Bernd
     
  7. Anonymous

    Anonymous Erfahrener Benutzer

    Registriert seit:
    15. Mai 2017
    Beiträge:
    762
    Danke erhalten:
    159
    Danke vergeben:
    197
    Müsste man in einem html text nicht eher 'gr&uuml;n' anstelle von 'grün' ersetzen?
     
  8. Anonymous

    Anonymous Erfahrener Benutzer

    Registriert seit:
    18. August 2021
    Beiträge:
    653
    Danke erhalten:
    88
    Danke vergeben:
    266
    #8 Anonymous, 7. Februar 2024
    Zuletzt bearbeitet: 7. Februar 2024
    Es kommt darauf an, wie es im HTML formatiert wurde. Normalerweise nicht, schau im Admin, oder in die DB, wie es dort steht.

    Wenn Du im Admin im Texteditor (CKEditor) hin-und her schaltest -> Test/html, dann wird grün so gr&uuml;' formatiert.

    Bleibst Du nur im Text-Modus, passiert nichts, dann bleibt grün grün :)

    Deshalb nehme ich oft bei SQL Befehlen beides.

    Edit:
    Sehe gerade, er hat's trotzdem umgestellt auf gr&uuml;

    Wie gesagt, ich nehme in solchen Fällen bei Änderungen oft beide Schreibweisen, zur Sicherheit.

    Wenn ich die Änderungen in der DB mache, schaue ich da mal rein, wie es dort geschrieben ist. Die Schreibweise in der DB ist maßgeblich, da man dort schreibweisekonform bleiben muss.

    In products_description wird's tatsächlich in gr&uuml;n formatiert.

    In products_name bleibt es bei grün.