php.de

Zurück   php.de > Webentwicklung > Datenbanken

Datenbanken SQL und Co

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 30.03.2010, 10:37  
Benutzer
 
Registriert seit: 03.04.2009
Beiträge: 66
Donald befindet sich auf einem aufstrebenden Ast
Standard Suche Tipps für MySQL -> Oracle

Hallo,

ich stehe vor der Aufgabe, dass meine PHP Anwendung neben MySQL in Zukunft auch Oracle unterstützen soll. Ich habe bereits alle Datenbank-Funktionen in ein externes Include ausgelagert, und würde dieses dann auch für Oracle anpassen. So kann die Anwendung später bei der Einrichtung entweder MySQL oder Oracle verwenden.

Jetzt mein Problem:
Die SQL-Anweisungen setze ich natürlich nicht in diesem Include zusammen. Ich habe in meiner Anwendung Oft diesen Fall:
PHP-Code:
$SQL "SELECT * FROM tbltesttabelle 
        WHERE LastActivity > '2010-03-27 23:59:59'
        ORDER BY LastActivity 
        LIMIT 10"
;
$db = new classDBOpen($SQL);
while(
$ROW $db->fetchObject()){
    
// do domething with the records

In diesem Beispiel habe ich zwei der bisher identifizierten Probleme eingebaut:

1. Das Datum muss bei Oracle immer mit TO_DATE() übergeben werden. Alle Datums-Query's müssten angepasst werden. Oder doch nicht?

2. Oracle kennt keine LIMIT Anweisung. Stattdessen soll ROWNUM verwendet werden. Laut diversen Google-Ergebnissen klappt das aber nicht in Verbindung mit ORDER BY, weil dann nicht die sortierten Ergebnisse limitiert werden. Alle Lösungen bauen den Query komplett um Ich kann nicht die ganze Anwendung doppelt anpassen.

Ich hab mir mal Datenbank-Frameworks angesehen, die angeblich von DB Unterschieden abschirmen sollen. Sie scheinen aber keine Lösung für meine Probleme darzustellen. Oder hab ich was übersehen?

Ich bin bereit, alle betroffenen Querys in der Anwendung umzubauen, aber ist das nötig? Weiterhin möchte ich dann nicht jeweils zwei Query's hinterlegen müssen. Am besten wäre eine Notation für alle Fälle.

Eine Idee:
PHP-Code:
$SQL "SELECT * FROM tbltesttabelle 
        WHERE LastActivity > " 
DBDate("2010-03-27 23:59:59") . 
        ORDER BY LastActivity " 
DBLimit(10); 
Hier würde ich Datumsangaben und eine LIMIT Klausel per Funktion anbauen. Für Oracle macht DBDate() dann eben den TO_DATE() hin und für MySQL nicht. Aber wie mache ich das mit LIMIT?

Bin gerade etwas Ratlos und verfluche Oracle immer öfter...

Donald
Donald ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 30.03.2010, 11:55  
thomas_w
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von Donald Beitrag anzeigen
Bin gerade etwas Ratlos und verfluche Oracle immer öfter...
Donald
Könnte auch damit zu tun haben, dass sich MySQL nicht an den SQL-Standard hält (siehe LIMIT) und deshalb ein Wechsel auf eine andere DB schwierig ist.

Aber am Besten schaust Du mal nach den diversen Migrations Tutorial von MySQL nach ORACLE und anderst herum. Da werden zu den meisten Thema auch Lösung aufgezeigt.

EDIT
Eventuell wäre PDO auch ein Thema.

Grüße
Thomas

Geändert von thomas_w (30.03.2010 um 11:56 Uhr). Grund: PDO ergänzt
  Mit Zitat antworten
Alt 30.03.2010, 15:22  
Benutzer
 
Registriert seit: 03.04.2009
Beiträge: 66
Donald befindet sich auf einem aufstrebenden Ast
Standard

Hi Thomas,

danke für deine Antwort. Die Lösungen kenn ich schon, aber ich müsste eben fast alle Queries in meinem Code anpassen. Und dafür suche ich eine Lösung. Zum Beispiel was das Datum betrifft, soll es eine Möglichkeit geben das Oracle so beizubringen dass es Datumsangaben immer mit Datum='YYYY-MM-DD HH:MM:SS' akzeptiert ohne TO_DATE() zu benötigen. Aber wie? Und kann ich vorhandene LIMIT Klauseln etwa durch automatisiertes umstellen (PHP soll den Query für Oracle anpassen) weiterhin verwenden?

Grüße,

Donald
Donald ist offline   Mit Zitat antworten
Alt 30.03.2010, 15:52  
thomas_w
Gast
 
Beiträge: n/a
Standard

Im Zend Framework wird das LIMIT für ORACLE so umgesetzt:

zend/db/adapter/oracle.php (Beispiel ZF 1.7.2)
PHP-Code:
        /**
         * Oracle does not implement the LIMIT clause as some RDBMS do.
         * We have to simulate it with subqueries and ROWNUM.
         * Unfortunately because we use the column wildcard "*",
         * this puts an extra column into the query result set.
         */
        
$limit_sql "SELECT z2.*
            FROM (
                SELECT ROWNUM AS zend_db_rownum, z1.*
                FROM (
                    " 
$sql "
                ) z1
            ) z2
            WHERE z2.zend_db_rownum BETWEEN " 
. ($offset+1) . " AND " . ($offset+$count);
        return 
$limit_sql
mit dem Datum könnte vielleicht der Weg über Prepare $stmt->bindParam() hilfreich sein. Habe es aber nicht probiert.

Grüße
Thomas

Geändert von thomas_w (30.03.2010 um 18:53 Uhr). Grund: bindParam() korrigiert
  Mit Zitat antworten
Alt 30.03.2010, 17:42  
Benutzer
 
Registriert seit: 03.04.2009
Beiträge: 66
Donald befindet sich auf einem aufstrebenden Ast
Standard

Hi Thomas,

vielen Dank für den ZEND Part. Das ist die Grundlage für meine Routine. Sie erkennt eine MySQL LIMIT Klausel (LIMIT Count oder LIMIT Offset, Count) und wandelt das in Oracle verträgliches um. Was denkt Ihr drüber? Ist da ein Fehler drinnen?

PHP-Code:
function ConvertOracleLimit($SQL) {
    
// find LIMIT position
    
$Pos strripos($SQL"limit ");
    if (
$Pos === FALSE) { 
        return 
$SQL// no LIMIT clause found, no need to do something
    
}
    
    
// find a following comma position (max. 8 chars later)
    
$PosComma stripos($SQL","$Pos);
    if (
$PosComma $Pos 8) {
        
$PosComma FALSE// too far away
    
}
    
    
// get min and count values
    
if ($PosComma === FALSE) {
        
// using no offset
        
$MinRow 1;
        
$Count intval(substr($SQL$Pos 56));
        
        
$PosRestBlank stripos($SQL" "$Pos 7);
        if (
$PosRestBlank === FALSE) { $PosRestBlank strlen($SQL); }
        
$PosRestLF stripos($SQL" "$Pos 7);
        if (
$PosRestLF === FALSE) { $PosRestLF strlen($SQL); }

    } else {
        
// using offset
        
$MinRow intval(substr($SQL$Pos 5$PosComma $Pos 5));
        
$Count intval(substr($SQL$PosComma 15));
        
        
$PosRestBlank stripos($SQL" "$PosComma 2);
        if (
$PosRestBlank === FALSE) { $PosRestBlank strlen($SQL); }
        
$PosRestLF stripos($SQL" "$PosComma 2);
        if (
$PosRestLF === FALSE) { $PosRestLF strlen($SQL); }

    }
    
    
// choose nearest end of limit (linefeed or a blank char)
    
if ($PosRestBlank $PosRestLF) {
        
$PosRest $PosRestBlank;
    } else {
        
$PosRest $PosRestLF;
    }

    
// remove original limit clause
    
$SQL substr($SQL0$Pos) . substr($SQL$PosRest);
    
    
// cover SQL by oracle specific limit variant
    
$limit_sql "SELECT z2.* FROM ( 
                        SELECT ROWNUM AS db_rownum, z1.* FROM ( 
                        $SQL
                        ) z1 
                  ) z2 
                  WHERE z2.db_rownum BETWEEN " 
. ($MinRow) . " AND " . ($MinRow+$Count); 
    return 
$limit_sql;

Ich werd das noch etwas schöner machen müssen, aber soweit klappt das hier schonmal ganz gut.

Donald

EDIT:
Mir fehlt nur noch eine Idee, wie ich verhindern kann das dass auch bei einem String wie "I accept no limit at all" greift. Das ist natürlich schwer...

Geändert von Donald (01.04.2010 um 09:59 Uhr).
Donald ist offline   Mit Zitat antworten
Alt 30.03.2010, 19:00  
thomas_w
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von Donald Beitrag anzeigen
EDIT:
Mir fehlt nur noch eine Idee, wie ich verhindern kann das dass auch bei einem String wie "I accept no limit at all" greift. Das ist natürlich schwer...
Stellt sich mir die Frage, was dass in einem SQL-String zu suchen hat, aber ein gültiger SQL-Befehl mit LIMIT sollte "SELECT", "UPDATE" oder "DELETE" enthalten. Darauf kannst Du den String ja durchsuchen, sonst ist es kein SQL-Befehl, bei dem LIMIT vorkommen kann.

Grüße
Thomas
  Mit Zitat antworten
Alt 30.03.2010, 19:18  
erc
Erfahrener Benutzer
 
Registriert seit: 02.01.2009
Beiträge: 730
PHP-Kenntnisse:
Fortgeschritten
erc wird schon bald berühmt werden
Standard

Zitat:
Zitat von Donald Beitrag anzeigen
Mir fehlt nur noch eine Idee, wie ich verhindern kann das dass auch bei einem String wie "I accept no limit at all" greift. Das ist natürlich schwer...
Das einfachste ist von hinten prüfen, LIMIT steht immer an letzter Stelle. Ausnahme sind Subqueries, aber die bekommst du definitiv so nicht umgewandelt.
erc ist offline   Mit Zitat antworten
Alt 30.03.2010, 20:42  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Zitat:
Sie erkennt eine MySQL LIMIT Klausel (LIMIT Count oder LIMIT Offset, Count) und wandelt das in Oracle verträgliches um. Was denkt Ihr drüber?
Eigentlich ganz einfach: Du musst das machen bevor Du Queryplatzhalter durch konkrete Werte überschreibst.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 01.04.2010, 09:58  
Benutzer
 
Registriert seit: 03.04.2009
Beiträge: 66
Donald befindet sich auf einem aufstrebenden Ast
Standard

Hallo,

Rückwärts suchen ist einfach zu realisieren. Einfach gleich zu beginn das "limit " nicht mit stripos() sondern mit strripos() suchen. Das sucht von hinten kommend.

PHP-Code:
$Pos strripos($SQL"limit "); 
Ich werd das in der geposteten Routine anpassen...

Ich habe meine Anwendung nach LIMIT durchsucht und finde keinen Query der LIMIT nicht am Ende hätte (also nicht in Subquery's). Evtl. könnte ich mit dieser Einschränkung leben...

Donald
Donald ist offline   Mit Zitat antworten
Alt 01.04.2010, 13:54  
Benutzer
 
Registriert seit: 03.04.2009
Beiträge: 66
Donald befindet sich auf einem aufstrebenden Ast
Standard

Hm,

jetzt ist das Datum noch ein Problem. Ich habe auch viele Datumsberechnungen in den Query's. Funktionen wie DATE_ADD, DATE_SUB oder auch DATE_FORMAT. Da gibts wohl keinerlei Kompatibilität, oder?

Donald
Donald ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] Suche Aufträge als PHP & MySQL Entwickler farr-networx Sonstige 0 10.02.2010 13:54
Suche PHP & MySQL Programmierer mac Beruflich 0 09.02.2010 17:00
Scriptsuche Suche Programmierer für kleines PHP MySQL Voting/Umfrage Script !!! Dominik995 Scriptbörse 0 18.11.2009 19:56
[Erledigt] Suche in MySQL via FORM 6setzen PHP Tipps 2009 8 18.09.2009 04:12
Suche Verstärkung mit schwerpunkt mysql, php, html Iluminare Beitragsarchiv 0 24.08.2009 22:04
[Erledigt] Suche Unterstützung (Freiberufler) für ein PHP - Mysql Projekt Stefano Beitragsarchiv 0 19.10.2008 09:58
Suche mit variabler Suchbegriffanzahl in MySQL Datenbank webbi Datenbanken 5 12.10.2006 17:06
Suche Tipps für Persormance-Steigerung (Geld für Nützliches) Beitragsarchiv 18 16.08.2005 10:57
Suche PHP & MySQL Programmierer Beitragsarchiv 4 11.08.2005 17:12
Suche Progger PHP, PERL, MYSQL, C++usw.. und Designer,Flash Beitragsarchiv 1 28.06.2005 17:12
[Erledigt] Suche über 2 Tabellen in MySQL PHP Tipps 2004-2 4 15.12.2004 16:05
Suche Php(evt Mysql) Leute Beitragsarchiv 14 12.12.2004 15:15
Suche MySQL referenz Datenbanken 2 17.11.2004 14:04

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php mysql to oracle, oracle limit offset, mysql to_date, \mysql oracle no\, php oracle limit, datum mysql nach oracle, wie kann ich in einer url ein datum an oracle übergeben?, php suchfunktion oracle datenbank, oracle php framework, oracle limit select, oracle sql php update, oracle limit befehl, oracle limit klausel, mysql order string blank, http://www.php.de/datenbanken/66317-suche-tipps-fuer-mysql-oracle.html, oracle limit nach order by, php mysql oracle, oracle offset, oracle datumsberechnung, to_date mysql

Alle Zeitangaben in WEZ +2. Es ist jetzt 10:06 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum