search
subnavi
Werbung

Datenbanken: Sybase

Sybase ist ein kommerzielles RDBMS. Eine komplette FAQ ist unter The Sybase FAQs zu finden. Hier geht es lediglich um die PHP-Aspekte.

Frage: Sybase-DB oder Sybase-CT?

Antwort von Timm Friebe:

Der Unterschied wird in der Sybase FAQ erklärt: 7.2: What is the difference between DB-lib and CT-lib? (Englisch).

Am besten also PHP --with-sybase-ct[=/pfad/zu/sybase/libraries] compilieren.

Frage: FreeTDS

Antwort von Timm Friebe:

Für alle, die nicht in den Genuss der Sybase-Client-Libraries kommen, gibt es FreeTDS - das ist eine freie Implementation des der Sybase zugrundeliegenden TDS- ("Tabular Data Streams") Protokolls. FreeTDS ist in der Version 0.62 relativ stabil (und auf jeden Fall ausreichend stabil für normale PHP-Anwendungen). Einige Bugs zeigen sich beim Canceln von Resultsets auf, die sich je nach Lage entweder in Segmentation Faults oder unendlich vielen Meldungen "Unknown Marker: XXX" äußern. PHP "cancelt" alle Resultsets bis auf das erste - multiple Resultsets werden beispielsweise von der Stored Procedure sp_help zurückgegeben.

Für die freetds.conf ist die TDS-Version 5.0 zu wählen. Beispiel:

[gurke]
        host = 127.0.0.1
        port = 1999
        tds version = 5.0 

Frage: String-Quoting bei Sybase

Antwort von Timm Friebe:

Bei Sybase müssen Anführungsstriche Strings innerhalb von Queries nicht mit einem Backslash (\), sondern mit dem jeweils gleichen Zeichen escaped werden. Folgendes Beispiel sollte das anschaulich machen:

select "Er sagte: ""Hallo Welt"""
select 'Das gibt''s doch nicht' 

Eine Komfort-Funktion, die sich darum kümmert, dass in SQL-Statements immer richtig gequotet wird, soll hier gezeigt werden:

function sybase_prepare() {
  $args= func_get_args();
  $sql= $args[0];
  if (sizeof($args)<= 1) return $sql;
  $j= 0;    
  $sql= $tok= strtok($sql, '%');
  while (++$j && $tok= strtok('%')) {
    $arg= (is_object($args[$j]) && method_exists($args[$j], 'toString') 
      ? $args[$j]->toString()
      : $args[$j]
    );
    switch ($tok{0}) {
      case 'd': 
        $sql.= ($arg === NULL ? 'NULL' : intval($arg)).substr($tok, 1); 
        break;
        
      case 'c': 
        $sql.= substr($tok, 1); 
        break;
        
      case 's': 
        $sql.= ($arg === NULL ? 'NULL' : "'".str_replace("'", "''", $arg)."'").substr($tok, 1); 
        break;
        
      default: 
        $sql.= '%'.$tok; $j--;
    }
  }
  return $sql;
}

// Beispiel 1
$sql= sybase_prepare('
  insert into person (
    person_id, name, company
  ) values (
    %d, %s, %s
  )',
  1,
  'Dau Jones',
  NULL
);

// Beispiel 2
class Date {
  var $utime;
  
  function Date($utime) {
    $this->utime= $utime;
  }
  
  function toString($fmt= 'Y-m-d H:i:s') {
    return date($fmt, $this->utime);
  }
}

$date= &new Date(time());
$sql= sybase_prepare(
  'select count(*) from %c where lastchange= %s',
  'account',
  $date
); 
Antwort von Kerry W. Lothrop:

Durch das Einschalten des Parameters magic_quotes_sybase ändert sich auch das Verhalten der Funktion addslashes() , selbst wenn die Parameter magic_quotes_gpc und magic_quotes_runtime deaktiviert sind.

$string = '\' \ "';

// magic_quotes_sybase = Off
echo addslashes($string);
Ergibt \' \\ \"

// magic_quotes_sybase = On
echo addslashes($string);
Ergibt '' \ " 

Frage: MySQL-Kompatibilität: Tabellen auflisten

Antwort von Timm Friebe:

Bei MySQL gibt es die Funktion mysql_list_tables() , um Tabellen innerhalb der aktuellen Datenbank aufzulisten. Bei Sybase gibt es die Funktion nicht, hier muss auf den folgenden Select zurückgegriffen werden:

select name from sysobjects where type= 'U' 

Frage: MySQL-Kompatibilität: Datenbanken auflisten

Antwort von Timm Friebe:

Analog dazu wird eine Liste der Datenbanken abgefragt. Während MySQL die Funktion mysql_list_dbs() kennt, muss bei Sybase folgender Select verwendet werden:

select name from master..sysdatabases 

Frage: MySQL-Kompatibilität: Server-Info

Antwort von Timm Friebe:

Die Funktion mysql_get_server_info() kann wie folgt emuliert werden:

select @@version 

Ein Ausgabe-Beispiel ist SQL Server/11.0.3.3 ESD#6/P-FREE/Linux Intel/Linux 2.2.14 i686/1/OPT/Fri Mar 17 15:45:30 CET 2000

Frage: MySQL-Kompatibilität: Prozesse auflisten

Antwort von Timm Friebe:

Eine Liste der aktiven Prozesse (wie mysql_list_processes() ) kann wie folgt abgerufen werden:

select 
  p.spid, 
  p.hostname, 
  p.cmd, 
  d.name 
from 
  master..sysprocesses p, 
  master..sysdatabases d 
where 
  d.dbid= p.dbid 

Frage: Sybase: Changed database context...

Antwort von Timm Friebe:

Die Warning Sybase: Changed database context... kann entweder durch das Voranstellen des Zeichens @ vor die Funktion sybase_select_db() oder aber dauerhaft durch das Ändern des INI-Eintrags sybct.min_server_severity auf den Wert 11 (per Default ist dieser 10 ) erreicht werden.

Frage: Hostnamen definieren

Antwort von Timm Friebe:

Der Hostname (wie in sp_who zu sehen) ist per Default das relativ unaussagekräftige "PHP 4.0". Dieser Wert kann über den INI-Eintrag sybct.hostname auf einen beliebigen Wert geändert werden (bspw. "oltp" oder "cronjob").

Frage: Textfelder

Antwort von Timm Friebe:

In Sybase gibt es Datenfelder vom Typ text , die bis zu 2 GB Daten enthalten können. Bei einem Select mit PHP werden jedoch nur 32 KiloByte gelesen. Sollen mehr Daten gelesen werden können, muss vorher folgender Query abgesetzt werden:

set textsize <<max_bytes>> 

Sollen maximal 256 Kilobyte gelesen werden können, sähe das also so aus:

set textsize 262144