Peter Rehm's Blog

apple,development,life & more

MSSQL to MySQL konvertieren

Ohne Kommentare

In einem aktuellen Projekt stand ich vor der Herausforderung, dass die bisherige Datenbank
in MSSQL gehalten wurde, und ich die Datenbank nur umständlich über ein Weboberfläche
"verwalten" konnte.

Da ich wenigstens die aktuelle Datenstruktur ansehen wollte, den Code der zu dem Projekt
gehört kann eh nicht weiterverwendet werden, musste ich irgendwie ein SQL Statement
erzeugen, was mit dem Tool aber nicht möglich war.

Dann stieß ich auf das MySQL Migration Toolkit, mit welchem man an sich
komfortabel eine MSSQL Datenbank auslesen könnte, und direkt in eine MySQL Datenbank
schreiben kann. Allerdings war, wie nicht anders zu erwarten, der SQL Server nicht von außen
zugänglich.

Die einzige Lösung die somit noch blieb war über ein PHP/ASP Skript, was direkt auf dem
Server liegen kann und soch somit auch verbinden kann. Nach längerer Suche stieß ich auf
das Greenlight SQL Tool.

Aus dem heruntergeladenen ZIP Archiv muss man nur noch die dumpdb.php hochladen und
anpassen. In meinem Fall wollte ich eine MSSQL DB auslesen und in ein MySQL Format bringen.

Standardmäßig sieht der erste teil der Config so aus

CODE:
$dbpasswd = @$HTTP_POST_VARS["dbpasswd"];
$dbhost = (! empty($HTTP_POST_VARS["dbhost"])) ? $HTTP_POST_VARS["dbhost"]
    : "localhost";
$dbname = @$HTTP_POST_VARS["dbname"];
$dbuser = @$HTTP_POST_VARS["dbuser"];
$dbtype = (! empty($HTTP_POST_VARS["dbtype"])) ? $HTTP_POST_VARS["dbtype"]
    : (function_exists("mssql_connect") ? "mssql" : "mysql");
$targetType = (! empty($HTTP_POST_VARS["targetType"]))
     ? $HTTP_POST_VARS["targetType"] : $dbtype;


Woher die HTTP_POST_VARS kommen sollen, war mir unklar daher habe ich das wie folgt
angepasst.

CODE:
$dbpasswd ='pass';
$dbhost = 'localhost';
$dbname = 'db123';
$dbuser = 'user123';
$dbtype = 'mssql';
$targetType = 'mysql';


Nun kann man das Skript über den Browser aufrufen und erhält die Datei direkt zum
Download. Ist dies nicht der Fall fehlt vermutlich PEAR::DB, welches unbedingt vorhanden
sein muss.

Dies kann man allerdings auch direkt in das Verzeichnis hochladen, wenn PEAR nicht
direkt gegeben ist. Auf dies komme ich in einem der nächsten Blog Einträge zurück.

Geschrieben von Peter Rehm

19.03.2007 um 09:19:21

Abgelegt in Programmierung

Tags für diesen Artikel: , ,

Suchen und Ersetzen mit MySQL

Ohne Kommentare

Ein Szenario, das sicher einigen bekannt vor kommt. Ein Kunde pflegt seine Daten über
einen längeren Zeitraum. Eines Tages möchte er einen Pfad den er dort immer eingegeben
hat ändern und hat keine Lust dazu alle Artikel nochmals zu bearbeiten.
Er meldet sich und sagt, man solle das doch "kurz" für Ihn erledigen.

Dank der REPLACE Funktion von MySQL auch in der Tat kein Problem.

CODE:
UPDATE articles
SET content = REPLACE (content,'alt','neu')


Geschrieben von Peter Rehm

18.03.2007 um 10:33:54

Abgelegt in Programmierung

Tags für diesen Artikel:

CSV Dateien in MySQL importieren

Ohne Kommentare

Ich musste gerade eine Reihe Postleitzahlen importieren, daher habe ich eine Quick & Dirty Lösumg geschrieben um CSV Dateien zu importieren.

CODE:
<?php

class csv2mysql
{
/**
* DB Host
*/
var $host='';

/**
* DB User
*/
var $user='root';

/**
* DB Pass
*/
var $pass='';

/**
* DB Name
*/
var $db;

/**
* Table Name
*/
var $table;

/**
* CSV Separator
*/
var $separator=';';

/**
* Filename to import
*/
var $filename;

/**
* DB Handle
*/
var $db_handle;

/**
* File Handle
*/
var $file_handle;

/**
* Max Line length in CSV File
*/
var $max_line_length=1000;

/**
* Insert Count
*/
var $count=0;

/**
* Konstruktor to set the options
*
* options: dbname,tablename,separator
*/
function csv2mysql($options)
{
if(empty($options['dbname']))
{
die("you have to enter a database name!");
} else {
$this->db=$options['dbname'];
}

if(empty($options['table']))
{
die("you have to enter a table name!");
} else {
$this->table=$options['table'];
}

if(empty($options['filename']))
{
die("you have to enter a filename!");
} else {
$this->filename=$options['filename'];
if(!file_exists($this->filename))
{
die("file does not exist");
}
}

if(!empty($options['separator']))
{
$this->separator=$options['separator'];
}

$this->db_handle=mysql_connect($this->host,$this->user,$this->pass);
mysql_select_db($this->db,$this->db_handle);

return;
}

function convert()
{
$this->file_handle=fopen($this->filename,"r");
if($this->file_handle && $this->db_handle)
{
while($data=fgetcsv($this->file_handle,$this->max_line_length,$this->separator))
{
$res=mysql_query("INSERT INTO ".$this->table."
 VALUES (".join($data,',').")",$this->db_handle) or die(mysql_error());
if($res)
{
$this->count++;
}
}
echo $this->count;
} else {
die("could not open file or database");
}
}
}

$imp=new csv2mysql(array('filename'=>'/www/test.csv',
'dbname'=>'plzdb',
'table'=>'plz'));
$imp->convert();
?>


Aufgrund den anstehenden Prüfungen verzichte ich auf das erklären des Codes, das müsste man auch so verstehen können :-)

Geschrieben von Peter Rehm

18.01.2007 um 21:33:35

Abgelegt in PHP

Tags für diesen Artikel: , , ,

MySQL Backups

Ohne Kommentare

Nur der vollständigkeit halber auch eine Kurzanleitung zum erstellen eines MySQL Dumps.

CODE:
mysqldump -u root --all-databases > /Volumes/Backup/backup_sync/all_db_dump.sql


So werden alle Datenbanken von der MySQL Datenbank localhost in die eine Datei gedumpt.
Man hat auch hier vielfältige Optionen, um das alles genauer einzustellen.

Wichtig ist noch, wenn man ein Passwort für den Benutzer Root gesetzt hat, dass man
dann die -p Option benötigt.

CODE:
mysqldump -u root -p --all-databases > /Volumes/Backup/backup_sync/all_db_dump.sql


Und mit dem Parameter -h kann man den Hostname bestimmen. In der Regel wird localhost
verwendet, wenn man nichts angibt.

Geschrieben von Peter Rehm

07.01.2007 um 17:25:00

Tags für diesen Artikel: ,

UTF-8 in Webapplikationen

Mit 3 Kommentaren

Um mein CMS auch in bulgarisch betreiben zu können, musste ich mich nun mit UTF-8 beschäftigen.

Die Erfahrungen will ich hier nun kundtun.

Es ist vielleicht noch keine perfekte Lösung, aber Sie tut erstmal Ihren Dienst.

Allgemeines

Zum ersten muss dem Browser gesagt werden, welches Charset verwendet werden soll, nämlich UTF-8.
Dies ist vor allem dann ein Problem wenn der Browser das selbst festlegt, kann man böse Überraschungen
erhalten.

CODE:
<meta http-equiv="content-type" content="application/xhtml+xml;charset=utf-8" />


Dies sollte überall eingebunden werden. Man kann auch in der Css festlegen, welche Zeichensatz
verwendet werden soll, dies habe ich bisher aber noch nicht benötigt :-)

CODE:
@charset "utf-8";


Praktisch ist vor allem im Umgang mit PHP, die Anwendung von header()

CODE:
header('content-type: text/html; charset=utf-8');


Man kann dies auch in der php.ini spezifizieren, sofern man Zugriff darauf hat. (default_mimetype & default_charset)

Damit der Besucher der Website auch in allen Formularen UTF-8 eingeben kann sollte man
accept-charset in den FORM-Kopf mit aufnehmen.

CODE:
<form accept-charset="utf-8" method=…


Der Vollständigkeit halber auch noch die Einbindung in XML

CODE:
<?xml version="1.0" encoding="utf-8"?>


PHP

All diese Einstellungen machen es möglich, dass UTF eingegeben und ausgegeben werden kann.
Die meisten die das verwenden haben allerdings eine Datenbank im Hintergrund, und schon da kann
es komplizierter werden. Als erstes benötigen wir eine Funktion, die überprüft ob ein String bereits
UTF-8 ist:

CODE:
/**
* Checks if String is UTF-8 Encoded
* @param string $string string to check
* @return boolean
*/
function is_utf8($string) 
{
return preg_match('%^(?:
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*$%xs', $string);
}


Dies ist nach der Vorgabe von W3.
Somit kann nun schoneinmal festgestellt werden ob der String utf8 ist.

Nun noch eine Funktion, die UTF8 encodiert. Achtung, die Funktion benötigt is_utf8()

CODE:
/**
* Encodes String to UTF8
* @param string $string
* @return string
*/
function cms_utf8_encode($string)
{
if(is_utf8($string))
{
return $string;
} else {
if(function_exists('mb_convert_encoding'))
{
return mb_convert_encoding($string,'utf-8');
} else {
return utf8_encode($string);
}
}
}


Hier wird der String encodiert, bevor er z.B. in die Datenbank geschrieben wird.

Datenbank

Ich habe mich auch mit dem Thema UTF-8 und Datenbank auseinandergesetzt. Dabei muss man folgendes Wissen:
UTF-8 kostet mehr als z.B. der latin1 Zeichensatz, da mehr Speicherplatz verwendet wird. Sogar 3x soviel :-)
Daher habe ich mich dazu entschlossen, da in der regel die wenigsten Zeichen in meinem System in Unicode gespeichert werden sollen, den latin1 Zeichensatz zu lassen.

Ich encodiere nur UTF-8 und leg das eben dann so ab. Funktioniert wunderbar, und ich hoffe das gibt keine Probleme.

In dem zug auch eine sehr detaillierte Beschreibung zu dem Thema von Kris Köhntopp.

Geschrieben von Peter Rehm

18.11.2006 um 14:05:13

Tags für diesen Artikel: , , , ,

MySQL Berechtigungen in Confixx

Ohne Kommentare

Nach meinem Umstieg auf S9Y wollte ich einen Artikel suchen und bekam sofort eine Fehlermeldung.

CODE:
Die Suche konnte nicht wie gewünscht ausgeführt werden. 
Hinweis für den Administrator dieses Blogs: Der Fehler kann durch fehlende 
Index-Schlüssel der Datenbank verursacht werden. Auf MySQL-Systemen 
muss der Datenbankbenutzer-Account in der Lage sein, Index-Schlüssel 
zu erstellen und folgende Abfrage auszuführen: 

CREATE FULLTEXT INDEX entry_idx on serendipity_entries (title,body,extended);
...


Der Index konnte auch nicht manuell erstellt werden, da dem Benutzer schlichtweg die Rechte dazu fehlen.
Dies ist eine Standardeinstellung des Verwaltungstools Confixx.
Dies ist in meinem Fall bei einem Managed Server sehr ärgerlich, und ich hab sofort den Support benachrichtigt, der meinte das kann man nicht umstellen.

Eine Lange Recherche im Internet brachte auch keien Erfolg, und ich nahm gleich Kontakt mit SW-Soft, dem Hersteller von Confixx auf. Von dem Support Team erhielt ich umgehend folgene Hilfestellungen:

CODE:
MySQL Rechte können in der Datei 
../confixx/html/include/class.MysqlPermissions.php eingestellt werden.

Oder man kann die Berechtigungen manuell in der Datenbank 'mysql' setzten.
In diesem Fall muss man auch die Variable $restore_users_permissions in der 
Datei confixx_main.conf auf '0' setzen. Sonst werden die Berechtigungen wieder 
überschrieben.


Vielen Dank an das Support Team von Confixx und ich hoffe, dass mein Provider das nun auch so umsetzen kann!

Geschrieben von Peter Rehm

03.11.2006 um 12:52:44

Abgelegt in Web

Tags für diesen Artikel: , , ,

ADODB Table Prefix

Ohne Kommentare

Bei fast jedem Projekt arbeitet man mit Tabellen Prefixen, um das Projekt z.b. 2x in der gleichen Datenbank laufen zu lassen. Gestern habe ich angefangen mein Projekt auf ADOBD und dabei festgestellt dass es noch keine eingebaute Funktion für das Verwalten eines Prefixes gibt. Daher hab ich das nun auf meine Anforderungen angepasst.

Mein Prefix liegt in $cfg['tbl_prefix'].

Die Querys werden nun so aufgebaut ("SELECT * FROM ##daten").

Statt Execute nimmt man nun die neue Funktion pExecute.

Diese Funktion muss in die adodb.inc.php implementiert werden, ich hab diese in der aktuellen ADODB Version in Zeile 784 direkt vor Execute plaziert.

CODE:
/**
*    Function to Replace the Prefixes
*    After replacing it the SQL Statement will be passed to EXECUTE()
*    @param sql SQL statement to execute, ## will be replaced with the Prefix
*/
function &pExecute($sql)
{
global $cfg;
return $this->Execute(str_replace('##',$cfg['tbl_prefix'],$sql));
}

Geschrieben von Peter Rehm

28.06.2006 um 10:39:27

Abgelegt in PHP, Programmierung

Tags für diesen Artikel: ,

MySQL Probleme unter OSX

Ohne Kommentare

Wer unter OSX folgenden Fehler bekommt:

CODE:
Can't connect to local MySQL server through socket '/var/mysql/mysql.sock'


Kann nun wieder durchatmen und mir einen ausgeben

CODE:
sudo mkdir /var/mysql
sudo ln -s /private/tmp/mysql.sock /var/mysql/mysql.sock


Und dein Tag ist gerettet! ;-)

Geschrieben von Peter Rehm

11.06.2006 um 22:11:29

Abgelegt in Verschiedenes

Tags für diesen Artikel: