<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kau-Boys blog &#187; MySQL</title>
	<atom:link href="http://kau-boys.de/tag/mysql/feed" rel="self" type="application/rss+xml" />
	<link>http://kau-boys.de</link>
	<description>Webdevelopment and more</description>
	<lastBuildDate>Thu, 29 Jul 2010 22:09:53 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>MySQL unter PHP debuggen mit einer eigenen MySQL Klasse</title>
		<link>http://kau-boys.de/webentwicklung/mysql-unter-php-debuggen-mit-einer-eigenen-mysql-klasse?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=mysql-unter-php-debuggen-mit-einer-eigenen-mysql-klasse</link>
		<comments>http://kau-boys.de/webentwicklung/mysql-unter-php-debuggen-mit-einer-eigenen-mysql-klasse#comments</comments>
		<pubDate>Thu, 04 Mar 2010 22:41:07 +0000</pubDate>
		<dc:creator>Bernhard</dc:creator>
				<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://kau-boys.de/?p=794</guid>
		<description><![CDATA[Bei einem meiner Projekte kam es zu ungew&#246;hnlich langen Ladezeiten eines Formulars. Da hier allerdings auch sehr viele Datenbankabfragen ausgef&#252;hrt werden m&#252;ssen und dabei auch noch die Werte per COUNT() gez&#228;hlt werden wunderten mich die Zeiten nicht wirklich. Nun wollte ich nat&#252;rlich wissen, welche Abfrage dabei besonders viel Zeit in Anspruch nimmt um dann gezielt [...]]]></description>
			<content:encoded><![CDATA[<p>Bei einem meiner Projekte kam es zu ungew&#246;hnlich langen Ladezeiten eines Formulars. Da hier allerdings auch sehr viele Datenbankabfragen ausgef&#252;hrt werden m&#252;ssen und dabei auch noch die Werte per <a href="http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_count">COUNT()</a> gez&#228;hlt werden wunderten mich die Zeiten nicht wirklich.</p>
<p>Nun wollte ich nat&#252;rlich wissen, welche Abfrage dabei besonders viel Zeit in Anspruch nimmt um dann gezielt optimieren zu k&#246;nnen. Ich setze in dem Projekt auf die <a href="http://de.php.net/manual/en/book.mysqli.php">MySQLi Klasse</a> von PHP. Da ich hierbei die Klasse objektorientiert nutze, war es sehr einfach m&#246;glich diese zu erweiterten. Eine M&#246;glichkeit w&#228;re es nat&#252;rlich gewesen eine eigene Funktion zu schreiben, aber in diesem Fall h&#228;tte ich auch alle Skript anpassen m&#252;ssen, in denen ich eine Query ausf&#252;hre. Daher habe ich mich dazu entschlossen einfach die <a href="http://de.php.net/manual/en/mysqli.query.php">query() Funktion</a> von MySQLi zu &#252;berschreiben. Hier ein stark vereinfachtes Beispiel, wie so etwas aussehen k&#246;nnte:</p>
<p><span id="more-794"></span></p>
<pre class="brush: php;">
&lt;?php

class mysqliDebugger extends mysqli {

	public $queries = array();
	public $queries_time = 0;

	function __construct($host, $user, $pass, $name, $port, $sock){
		parent::__construct($host, $user, $pass, $name, $port, $sock);
	}

	function __destruct(){
		parent::__destruct();
	}

	function query($query){
		$start = microtime(true);

		if(!$result = parent::query($query)){
				$error_message = $this-&gt;error;
		}

		$end = microtime(true);

		$this-&gt;queries[] = array(
			'number' =&gt; count($this-&gt;queries),
			'query' =&gt; $query,
			'error' =&gt; $error_message,
			'time' =&gt; $end - $start
		);

		$this-&gt;queries_time += $end - $start;

		return $result;
	}
}

$mysqli = new mysqliDebugger('host', 'user', 'pass', 'name');
if($result = $mysqli-&gt;query('SELECT * FROM tablename')){
	while($row = $result-&gt;fetch_assoc()){
		// Verarbeiten der Ergebniszeilen
	}
}

if($result = $mysqli-&gt;query('SELECT * FROM tablename2')){
	while($row = $result-&gt;fetch_assoc()){
		// Verarbeiten der Ergebniszeilen
	}
}

?&gt;
</pre>
<p>Sehen wir uns die wichtigsten Zeilen des Quellcodes an. Die Zeilen 8-10 zeigen den Konstruktor unserer neuen Klasse, die den Konstruktor der geerbten Klasse MySQLi aufruft. In den Zeilen 16-36 &#252;berschreiben wir die query() Funktion der MySQLi Klasse mit unserer Debugging-Klasse. Dort wird zuerst einmal zur Protokollierung der Ausf&#252;hrungszeit der Startzeitpunkt mit Hilfe der <a href="http://de.php.net/manual/en/function.microtime.php">microtime() Funktion</a> ermittelt. Anschlie&#223;end wird der Query mit dem Aufruf <code>parent::query($query)</code> an die query() Funktion der MySQLi Klasse &#252;bergeben. Einen eventuell auftretenden Fehler speichern wir dabei in einer Variablen ab.</p>
<p>In Zeile 23 speichern wir die Endzeit des Query. Anschlie&#223;end speichern wir alle Werte, die wir zur sp&#228;teren Auswertung ben&#246;tigen in einem Array gespeichert. Zus&#228;tzlich summieren wir noch alle Zeiten auf, um sp&#228;ter die Gesamtdauer aller Statements bestimmen zu k&#246;nnen. Die ab Zeile 38 wird eine einfache Instanziierung und Nutzung der Klasse aufgezeigt, wie man sie auch von MySQLi kennt. Wer also in seinen Skripten schon MySQLi verwendet kann einfach beim Instanziieren der Klasse die neue Debugging-Klasse verwenden und muss keine weiteren Zeilen im Quellcode &#228;ndern. Ich empfehle eine kleine Bedingung zu verwenden, die feststellt, ob der Debugging-Modus aktiv ist und nur dann die Debugging-Klasse zu verwenden, wenn sie auch ben&#246;tigt wird. Das spart im produktiven Einsatz etwas Rechenzeit. Eine m&#246;gliche Bedingung k&#246;nnte wie folgt aussehen:</p>
<pre class="brush: php; gutter: false;">
if($debug){
	$mysqli = new mysqliDebugger('host', 'user', 'pass', 'name');
} else {
	$mysqli = new mysqli('host', 'user', 'pass', 'name');
}
</pre>
<p>Anstelle der <code>$debug</code> Variablen k&#246;nntet ihr auch einen GET Parameter oder einen Session Parameter verwenden. Ich rate aber dringend davon ab einen einfach zu erratenden GET Parameter zu verwenden, da in solchen F&#228;llen eure SQL-Statements f&#252;r Unbefugte sichtbar werden k&#246;nnten, was unter Umst&#228;nden die Sicherheit eueres Systems gef&#228;hrden k&#246;nnte.</p>
<p>Nachdem wir die Daten gesammelt haben m&#246;chten wir sie nat&#252;rlich auch ausgeben. Das solltet ihr auch wieder die vorherige Bedingung verwenden. Dazu erstellen wir einfach eine Tabelle, die die gesammelten Daten enth&#228;lt:</p>
<pre class="brush: xml;">
&lt;table style=&quot;border: 1px solid #000;&quot; rules=&quot;all&quot;&gt;
	&lt;caption&gt;Gesamtdauer: &lt;?= $mysqli-&gt;queries_time ?&gt;&lt;/caption&gt;
	&lt;tr&gt;
		&lt;th&gt;Anzahl&lt;/th&gt;
		&lt;th&gt;Query&lt;/th&gt;
		&lt;th&gt;Fehler&lt;/th&gt;
		&lt;th&gt;Zeit&lt;/th&gt;
	&lt;/tr&gt;
&lt;? foreach($mysqli-&gt;queries as $query) : ?&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;?= $query['number'] ?&gt;&lt;/td&gt;
		&lt;td&gt;&lt;?= $query['query'] ?&gt;&lt;/td&gt;
		&lt;td&gt;&lt;?= $query['error'] ?&gt;&lt;/td&gt;
		&lt;td&gt;&lt;?= $query['time'] ?&gt;&lt;/td&gt;
	&lt;/tr&gt;
&lt;? endforeach ?&gt;
&lt;/table&gt;
</pre>
<p>Nehmen wir an, wir die Tabelle aus dem ersten Statement ist in der Datenbank nicht vorhanden. In diesem Fall w&#252;rden wir einen SQL-Fehler erhalten. In der Tabelle k&#246;nnen wir dann direkt den Fehler ermitteln und entsprechend das Statement korrigieren. Auch hier wird das Statement gespeichert und die Zeit gemessen.</p>
<table style="color: rgb(185, 189, 182); background-color: rgb(27, 36, 38); width: 100%; padding: 5px; border: 1px solid #000;" rules="all">
<caption style="background-color: rgb(27, 36, 38);">Gesamtdauer: 0.0025820732116699</caption>
<tr>
<th>Anzahl</th>
<th>Query</th>
<th>Fehler</th>
<th>Zeit</th>
</tr>
<tr>
<td>0</td>
<td>SELECT * FROM tablename</td>
<td>Table &#8216;name.tablename&#8217; doesn&#8217;t exist</td>
<td>0.00076198577880859</td>
</tr>
<tr>
<td>1</td>
<td>SELECT * FROM tablename2</td>
<td></td>
<td>0.0018200874328613</td>
</tr>
</table>
<p>Ihr habt mit dieser kleinen Beispiel-Klasse einen sehr einfachen Debugger zur Hand, mit dem ihr sehr schnell die langsamen Statements in eurem System finden k&#246;nnt. Ihr k&#246;nnt die Klasse nat&#252;rlich auch noch nach euren W&#252;nschen erweitern und auch andere Funktionen von MySQLi &#252;berschreiben. Wenn ihr, so wie ich, zentral an einer Stelle die Datenbankverbindung erzeugt k&#246;nnt ihr durch die Bedingung aus dem zweiten Quellcode eure gesamte Applikation debuggen.</p>
<p>Ich habe damit in meinem Projekt schon zwei &#252;berfl&#252;ssige Statements finden k&#246;nnen und einige andere Statements noch weiter optimieren k&#246;nnen. Ich hoffe, dass euch der Debugger auch bei eurer t&#228;glichen Arbeit unterst&#252;tzen kann. &#220;ber Anregungen und Kommentare Wrede ich mich wie immer freuen.</p>
]]></content:encoded>
			<wfw:commentRss>http://kau-boys.de/webentwicklung/mysql-unter-php-debuggen-mit-einer-eigenen-mysql-klasse/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Arrays und andere komplexe Daten mit PHP in einer MySQL-Datenbank speichern</title>
		<link>http://kau-boys.de/webentwicklung/arrays-und-andere-komplexe-daten-mit-php-in-einer-mysql-datenbank-speichern?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=arrays-und-andere-komplexe-daten-mit-php-in-einer-mysql-datenbank-speichern</link>
		<comments>http://kau-boys.de/webentwicklung/arrays-und-andere-komplexe-daten-mit-php-in-einer-mysql-datenbank-speichern#comments</comments>
		<pubDate>Sun, 24 Jan 2010 00:11:06 +0000</pubDate>
		<dc:creator>Bernhard</dc:creator>
				<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://kau-boys.de/?p=643</guid>
		<description><![CDATA[Viele von euch werden wohl schon einmal vor dem Problem gestanden haben, dass sie ein Array oder ein Objekt in der Datenbank speichern mussten. Hier m&#246;chte ich ein paar Vorschl&#228;ge unterbreiten, wie man das Problem nicht l&#246;sen sollte und wie es besser gehen kann. Der schlechte Weg Die einfachste und gleichzeitig auch schlechteste Methode w&#228;re [...]]]></description>
			<content:encoded><![CDATA[<p>Viele von euch werden wohl schon einmal vor dem Problem gestanden haben, dass sie ein Array oder ein Objekt in der Datenbank speichern mussten. Hier m&#246;chte ich ein paar Vorschl&#228;ge unterbreiten, wie man das Problem nicht l&#246;sen sollte und wie es besser gehen kann.</p>
<h2>Der schlechte Weg</h2>
<p>Die einfachste und gleichzeitig auch schlechteste Methode w&#228;re es, f&#252;r jeden Index eines Arrays oder jede Eigenschaft eines Objekts eine neue Spalte zu erzeugen. Bei diesem Ansatz werden unter Umst&#228;nden viele Zeilen erzeugt, die nicht immer einen Wert enthalten. Das ist zwar nicht so gravierend, aber durch diesen Ansatz erh&#246;ht sich auch die Anzahl der Spalten schnell auf eine un&#252;bersichtliche Anzahl. Zuletzt ist es hierbei bei jeder &#196;nderung des Arrays oder Objekts notwendig die Datenbanktabelle anzupassen.</p>
<p><span id="more-643"></span></p>
<h2>Eine bessere L&#246;sung gef&#228;llig?</h2>
<p>Etwas besser L&#246;sung, die fast immer funktioniert aber nicht f&#252;r alle F&#228;lle optimal ist, w&#228;re eine Serialisierung des Arrays oder Objekts. Hierbei werden die Daten mit der <a href="http://de.php.net/manual/en/function.serialize.php">serialize()</a> Funktion in einen String konvertiert und k&#246;nnen somit direkt in eine <a href="http://dev.mysql.com/doc/refman/5.1/en/char.html">VARCHAR</a> oder <a href="http://dev.mysql.com/doc/refman/5.1/en/blob.html">TEXT</a> Spalte speichert werden. Dabei muss der String nat&#252;rlich noch durch die Funktion <a href="http://de.php.net/manual/en/mysqli.real-escape-string.php">real_escape_string()</a> (in diesem Beispiel von der MySQLi Klasse) &#8220;escaped&#8221; werden.</p>
<h3>Speichern der Daten</h3>
<pre class="brush: php;">
// Das zu speichernde Array
$array = array('vorname' =&gt; 'Max', 'name' =&gt; 'Mustermann');
// Serialisieren der Daten
$string = serialize($array);
// Speichern der Daten
$mysqli-&gt;query('INSERT INTO table_name (array) VALUES (&quot;'.$mysqli-&gt;real_escape_string($string).'&quot;)'))
</pre>
<p>Das Beispiel setzt nat&#252;rlich voraus, dass die Variable <code>$mysqli</code> eine Instanz der MySQLi Klasse mit einer g&#252;ltige Verbindung zu einer Datenbank enth&#228;lt. Wir haben hier ein einfaches assoziatives Array, das serialisiert wird und anscheinend gespeichert wird. Die serialisierten Daten sehn in diesem Beispiel wie folgt aus:</p>
<h3>Der zu speichernde String</h3>
<pre class="brush: plain; gutter: false;">
a:2:{s:7:&quot;vorname&quot;;s:3:&quot;Max&quot;;s:4:&quot;name&quot;;s:10:&quot;Mustermann&quot;;}
</pre>
<p>Das Auslesen der Daten wird mit der Funktion <a href="http://de.php.net/manual/en/function.unserialize.php">unserialize()</a> durchgef&#252;hrt, die aus dem String wieder ein assoziatives Array erzeugt. Dazu lesen wir zuerst die Daten mit einem gew&#246;hnlichen Query aus und konvertieren anschlie&#223;end die Daten:</p>
<h3>Auslesen der Daten</h3>
<pre class="brush: php;">
// Auslesen der Daten
$result = $mysqli-&gt;query('SELECT array FROM table_name');
$row = $result-&gt;fetch_assoc();
$string = $row['array'];
// Unserialisieren der Daten
$array = unserialize($string);
</pre>
<p>Diese Methode zum Speichern von komplexen Daten funktioniert recht gut, aber der serialisierte String ben&#246;tigt dabei mehr Speicherplatz als f&#252;r ein normales assoziatives Array eigentlich n&#246;tig w&#228;re. Wie es eleganter geht zeige ich euch im n&#228;chsten Beispiel.</p>
<h2>Die elegante L&#246;sung mit JSON</h2>
<p>Das Format <a href="http://de.wikipedia.org/wiki/JSON">JSON</a> entspringt zwar der Skriptsprache JavaScript, aber es wird zu Zeiten von AJAX sehr oft auch serverseitig verwendet und erzeugt. Da die meisten serverseitigen Sprachen also auch JSON unterst&#252;tzen bietet es sich auch f&#252;r die Speicherung von komplexeren Datenstrukturen an. Die Anpassung des vorherigen Quellcodes beschr&#228;nkt sich dabei auch auf eine einzige Zeile. Wir ersetzen lediglich die serialize() durch die <a href="http://de.php.net/manual/en/function.json-encode.php">json_encode()</a> Funktion. Die Zeile 6 aus dem vorherigen Quellcode sieht dann folgt aus:</p>
<h3>Speichern der Daten</h3>
<pre class="brush: php; first-line: 3;">
...
$string = serialize($array);
...
</pre>
<p>Hierbei werden die Datei des assoziativen Arrays in die JSON Notation konvertiert. Hierbei ist der resultierende String kompakter als bei der Serialisierung, da die L&#228;nge der einzelnen Arraywerte nicht und Datentypen nicht gespeichert werden:</p>
<h3>Der zu speichernde String</h3>
<pre class="brush: jscript; gutter: false;">
{&quot;vorname&quot;:&quot;Max&quot;,&quot;name&quot;:&quot;Mustermann&quot;}
</pre>
<p>Beim Lesen der Daten aus der Datenbank m&#252;ssen sie dann selbstverst&#228;ndlich auch wieder in das urspr&#252;ngliche Format zur&#252;ck konvertiert werden. Dabei kommt wie ihr schon vermutet die Funktion <a href="http://de.php.net/manual/en/function.json-decode.php">json_decode()</a> zum Einsatz. Diese erzeugt aber normalerweise ein Standard-Objekt. Um das in unserem Beispiel verwendete assoziative Array zu erhalten, wird als zweiter Paramater &#8220;true&#8221; &#252;bergeben. Der &#196;nderung am Quellcode aus dem vorherigen Beispiel sieht dann wie folgt aus:</p>
<h3>Auslesen der Daten</h3>
<pre class="brush: php; first-line: 5;">...
$array = json_decode($string, true);
</pre>
<p>Die Verwendung von JSON sichert nicht nur die Daten sondern auch die Schl&#252;ssel eines Arrays. Dabei spielt es keine Rolle, ob das Array assoziativ ist oder Zahlen als Schl&#252;ssel verwendet. Auch wird die Sortierung dabei nicht ver&#228;ndert. Wer lediglich die Werte eines Array speichern m&#246;chte, also keine Schl&#252;ssel ben&#246;tigt, kann auch einen noch einfacheren Weg gehen.</p>
<h2>Array in der Datenbank light</h2>
<p>Der einfachste Werte mehrere Daten eines Array in einer Datenbank zu speichern sind die Funktionen <a href="http://de.php.net/manual/en/function.explode.php">explode()</a> und <a href="http://de.php.net/manual/en/function.implode.php">implode()</a>. Hierbei werden die einzelnen Werte des Arrays durch den &#8220;Delimiter&#8221;, den man als ersten Parameter angibt voneinander getrennt bzw. miteinander verbunden. Auch bei dieser Variante m&#252;ssen in den beiden Beispiel-Quellcodes nur die Funktionen f&#252;r die Umwandlung ausgetauscht werden. Zu beachte ist hierbei, dass der &#8220;Delimiter&#8221; nicht in den Werten vorkommen darf. Wer also beispielsweise ein Array mit Datumsangaben im Format 2010-01-23 mit implode verbinden m&#246;chte, darf nicht den Bindestrich als &#8220;Delimiter&#8221; verwenden.</p>
<p>Die Werte k&#246;nnen wie auch zuvor in einer VARCHAR oder TEXT Spalte gespeichert werden. Sehr hilfreich sind die beiden Funktionen aber auch beim Speichern in einer Spalte mit dem Spaltentyp <a href="http://">SET</a>. Da hierbei aber die Werte zus&#228;tzlich von Anf&#252;hrungsstrichen umgeben sein m&#252;ssen, muss der &#8220;Delimiter&#8221; auch die Anf&#252;hrungsstriche enthalten. Die implode Funktion w&#252;rde in der Speicherfunktion dann wie folgt eingesetzt:</p>
<h3>Speichern der Daten in einer SET Spalte</h3>
<pre class="brush: php; first-line: 3;">
...
$string = implode('&quot;, &quot;', $array);
...
</pre>
<h2>Fazit</h2>
<p>Wie ihr also seht, gibt es viele Wege komplexere Daten in einer Datenbank zu speichern. Das Beispiel mit JSON als Repr&#228;sentation sollte in jeder serverseitigen Skriptsprache funktionieren, die JSON unterst&#252;tzt. Solltet ihr PHP verwenden m&#252;sst ihr nat&#252;rlich auch sicherstellen, dass JSON bei euch aktiviert ist. Am einfachsten geht das wie immer mit Hilfe der <a href="http://de.php.net/manual/en/function.phpinfo.php">phpinfo()</a> Funktion, die in der Ausgabe einen &#8220;json&#8221; Abschnitt haben sollte.</p>
<p>Diejenigen von euch, die einen WordPress Blog haben und sich schon einmal die Datenbanktabelle angesehen haben, werden vermutlich die JSON Strings schon gesehen haben. Den WordPress speichert z.B. Arrays eines Plugins automatisch in der JSON Notation in der &#8220;options&#8221; Tabelle ab. Das macht es einem Pluginentwickler sehr einfach das Array zu speichern.</p>
<p>Ich hoffe, dass euch das kleine Tutorial weiterhelfen oder auf neue Ideen bringen konnte. &#220;ber Anregungen w&#252;rde ich mich wie immer sehr freuen.</p>
]]></content:encoded>
			<wfw:commentRss>http://kau-boys.de/webentwicklung/arrays-und-andere-komplexe-daten-mit-php-in-einer-mysql-datenbank-speichern/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Suchen-und-Ersetzen mit MySQL-Datenbanken</title>
		<link>http://kau-boys.de/datenbank/suchen-und-ersetzen-mit-mysql-datenbanken?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=suchen-und-ersetzen-mit-mysql-datenbanken</link>
		<comments>http://kau-boys.de/datenbank/suchen-und-ersetzen-mit-mysql-datenbanken#comments</comments>
		<pubDate>Wed, 23 Dec 2009 00:39:16 +0000</pubDate>
		<dc:creator>Bernhard</dc:creator>
				<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://kau-boys.de/?p=549</guid>
		<description><![CDATA[Vor ein paar Tagen musste ich ca. 1000 Datens&#228;tze, die fehlerhaft in eine Datenbank geschrieben wurden &#252;berarbeiten. In einer Spalte, die Links enth&#228;lt musste die Toplevel-Domain von .de auf .com ge&#228;ndert werden. Bis zu diesem Zeitpunkt war ich der Meinung, dass es nicht m&#246;glich ist ein Suchen-und-Ersetzen auf MySQL-Tabellen mit einem einfachen SQL-Statement durchzuf&#252;hren. In [...]]]></description>
			<content:encoded><![CDATA[<p>Vor ein paar Tagen musste ich ca. 1000 Datens&#228;tze, die fehlerhaft in eine Datenbank geschrieben wurden &#252;berarbeiten. In einer Spalte, die Links enth&#228;lt musste die Toplevel-Domain von .de auf .com ge&#228;ndert werden. Bis zu diesem Zeitpunkt war ich der Meinung, dass es nicht m&#246;glich ist ein Suchen-und-Ersetzen auf MySQL-Tabellen mit einem einfachen SQL-Statement durchzuf&#252;hren. In der Regel habe ich daher die Tabelle mit einem Programm wie Access verbunden und dort die Suchen-und-Ersetzen Funktion genutzt.</p>
<p>Die L&#246;sung f&#252;r das Problem war allerdings recht simpel. Ich habe f&#252;r Abfragen schon mehrfach die <a href="http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_replace">REPLACE() Funktion</a> von MySQL benutzt, die wie folgt definiert ist:</p>
<p><span id="more-549"></span></p>
<pre class="brush: sql; gutter: false;">
REPLACE(str,from_str,to_str)
</pre>
<p>Bisher habe ich aber die Funktion lediglich in einer Abfrage einsetzt, um direkt in einer Abfrage bestimmte Umformungen durchzuf&#252;hren, um z.B. nach den ge&#228;nderten W&#246;rtern gruppieren oder sortieren zu k&#246;nnen. Die REPLACE Funktion, die es auch schon in MySQL 4.1 gab, kann einem aber auch dabei helfen die Texte einer Spalte zu aktualisieren. Die Syntax f&#252;r eine Suchen-und-Ersetzen-Abfrage sieht wie folgt aus:</p>
<pre class="brush: sql; gutter: false;">
UPDATE [Tabellenname] SET [Spaltenname] = REPLACE([Spaltenname], [Suchwort], [Ersetzung])
</pre>
<p>Hierbei muss wie von vielen Programmen gew&#246;hnt nicht das gesamte Wort ersetzen werden. Wenn in einer Spalte das Suchwort meh als einmal gefunden wird, wird es auch mehrfach ersetzt. Zus&#228;tzlich kann in dem Update Statement nat&#252;rlich auch ein WHERE Statement eingebaut werden, um nicht alle Eintr&#228;ge einer Tabelle zu aktualisieren. Nehmen wir also an, es gibt eine Tabelle blogroll mit Links. In dieser wollen wir alle Links von .com auf .de &#228;ndern, aber keine Links, die auf example.com zeigen. Das Statement hierf&#252;r sieht dann wie folgt aus:</p>
<pre class="brush: sql; gutter: false;">
UPDATE blogroll SET link = REPLACE(link, '.com', '.de') WHERE link NOT LIKE '%example.com%'
</pre>
<p>Ihr k&#246;nnt somit sehr einfach in einer Tabelle Werte durch andere ersetzen. Ihr k&#246;nnt hierbei als Ersetzung auch weitere Funktionen nutzen wir z.B. die <a href="http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_concat">CONCAT() Funktion</a> mit der sich Texte oder Spalten zusammensetzen lassen.</p>
<p>Aber ihr m&#252;sst wie immer sehr vorsichtig mit UPDATE Statements umgehen, denn ein STRG + Z zum R&#252;ckg&#228;ngigmachen der Aktion gibt es nicht. Solltet ihr also nicht sicher sein, ob das Statement korrekt ist, gebt das Ergebnis der umformung zuerst mit einem SELECT Statement aus:</p>
<pre class="brush: sql; gutter: false;">
SELECT link, REPLACE(link, '.com', '.de') AS new_link FROM blogroll WHERE link NOT LIKE '%example.com%'
</pre>
<p>Am sichersten ist es nat&#252;rlich, wenn ihr die Daten der Tabelle vorher in einem SQL-Dump speichert. Ich hoffe dass der Tipp euch dabei helfen wird, wenn ihr mal ein &#228;hnliches Problem habt. Ich war ja bisher der Meinung, dass ich solche Ersetzungen immer nur auf einem Dump der Daten in einem Texteditor schnell durchf&#252;hren kann, aber nun werde ich diesen Trick vermutlich h&#228;ufiger einsetzen. </p>
]]></content:encoded>
			<wfw:commentRss>http://kau-boys.de/datenbank/suchen-und-ersetzen-mit-mysql-datenbanken/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
