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 ... ;
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.
@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
@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.
@WinHelp GmbH - @Pepe, vielen Dank für Eure Unterstützung. Ich werde das umsetzen. Vielen vielen Dank nochmals! Gruß Bernd
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ü' 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ü 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ün formatiert. In products_name bleibt es bei grün.