Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » SQL Anywhere Server - Programmierung » SQL Anywhere Datenzugriff-APIs » SQL Anywhere für Ruby

 

Ruby-DBI-Treiber für SQL Anywhere

Dieser Abschnitt bietet eine Übersicht darüber, wie Sie Ruby-Anwendungen schreiben, die den SQL Anywhere DBI-Treiber verwenden. Die vollständige Dokumentation für das DBI-Modul finden Sie im Internet unter [external link] http://ruby-dbi.rubyforge.org/.

DBI-Modul laden

Um die DBD:SQLAnywhere-Schnittstelle aus einer Ruby-Anwendung verwenden zu können, müssen Sie zuerst Ruby informieren, dass Sie das Ruby-DBI-Modul verwenden möchten. Dazu schreiben Sie die nachstehende Zeile an den Anfang der Ruby-Quelldatei.

require 'dbi'

Das DBI-Modul lädt, falls erforderlich, automatisch die Schnittstelle für den SQL Anywhere-Datenbanktreiber (DBD).

Verbindung öffnen und schließen

In der Regel öffnen Sie eine einzelne Verbindung zu einer Datenbank und führen dann alle erforderlichen Vorgänge durch, indem Sie eine Sequenz von SQL-Anweisungen ausführen. Öffnen Sie eine Verbindung mithilfe der connect-Funktion. Der Rückgabewert ist ein Handle zur Datenbankverbindung, mit dem Sie die nachfolgenden Vorgänge in dieser Verbindung durchführen.

Der Aufruf der connect-Funktion hat die allgemeine Form:

dbh = DBI.connect('DBI:SQLAnywhere:Servername', Benutzer-ID, Kennwort, Optionen)
  • Servername   Dies ist der Name des Datenbankservers, zu dem Sie eine Verbindung herstellen wollen. Alternativ können Sie auch eine Verbindungszeichenfolge im Format "Option1=Wert;Option2=Wert;..." angeben.

  • Benutzer-ID   Dies ist eine gültige Benutzer-ID. Wenn die Zeichenfolge nicht leer ist, wird ";UID=Wert" der Verbindungszeichenfolge angehängt.

  • Kennwort   Dies ist das entsprechende Kennwort für die Benutzer-ID. Wenn die Zeichenfolge nicht leer ist, wird ";PWD=Wert" der Verbindungszeichenfolge angehängt.

  • Optionen   Dies ist ein Hash mit zusätzlichen Verbindungsparametern wie z.B. DatabaseName, DatabaseFile und ConnectionName. Diese werden der Verbindungszeichenfolge im Format "Option=Wert1;Option=Wert2;..." angehängt.

Um die connect-Funktion zu veranschaulichen, starten Sie den Datenbankserver und die Beispieldatenbank, bevor Sie die Ruby Beispielskripten ausführen.

dbeng11 Beispielverzeichnis\demo.db

Das nachstehende Codebeispiel öffnet und schließt eine Verbindung zur SQL Anywhere-Beispieldatenbank. Die Zeichenfolge "demo" im untenstehenden Beispiel ist der Servername.

require 'dbi'
DBI.connect('DBI:SQLAnywhere:demo', 'DBA', 'sql') do |dbh|
    if dbh.ping
       print "Successfully Connected\n"
       dbh.disconnect()
    end
end

Optional können Sie auch eine Verbindungszeichenfolge statt des Servernamens angeben. Das obenstehende Skript kann beispielsweise geändert werden, indem Sie den ersten Parameter in der connect-Funktion folgendermaßen ändern:

require 'dbi'
DBI.connect('DBI:SQLAnywhere:ENG=demo;DBN=demo;UID=DBA;PWD=sql') do |dbh|
    if dbh.ping
       print "Successfully Connected\n"
       dbh.disconnect()
    end
end

Da die Benutzer-ID und das Kennwort in der Verbindungszeichenfolge angegeben sind, ist es nicht notwendig, Parameter 2 und 3 in der connect-Funktion anzugeben. Wenn Sie allerdings einen Hash aus zusätzlichen Verbindungsparametern übergeben, geben Sie eine leere Zeichenfolge ('') für die Benutzer-ID- und Kennwortparameter an.

Das folgende Beispiel zeigt, wie zusätzliche Verbindungsparameter an die connect-Funktion als Hash aus Schlüsselwort/Wert-Paaren übergeben werden können.

require 'dbi'
DBI.connect('DBI:SQLAnywhere:demo', 'DBA', 'sql', 
       { :ConnectionName => "RubyDemo",
         :DatabaseFile => "demo.db",
         :DatabaseName => "demo" }
        ) do |dbh|
    if dbh.ping
       print "Successfully Connected\n"
       dbh.disconnect()
    end
end
Daten auswählen

Nachdem Sie ein Handle für eine offene Verbindung erhalten haben, können Sie auf die Daten in der Datenbank zugreifen und sie ändern. Der einfachste Vorgang ist dabei, einige Zeilen abzurufen und auszudrucken.

Zuerst muss eine SQL-Anweisung ausgeführt werden. Wenn die Anweisung eine Ergebnismenge zurückgibt, verwenden Sie das resultierende Anweisungs-Handle, um Metainformationen über die Ergebnismenge und die Zeilen der Ergebnismenge abzurufen. Das folgende Beispiel bezieht die Spaltennamen aus den Metadaten und zeigt die Spaltennamen und die Werte für jede abgerufene Zeile an.

require 'dbi'

def db_query( dbh, sql )
    sth = dbh.execute(sql)
    print "# of Fields:  #{sth.column_names.size}\n"
    sth.fetch do |row|
        print "\n"
        sth.column_info.each_with_index do |info, i|
            unless info["type_name"] == "LONG VARBINARY"
                print "#{info["name"]}=#{row[i]}\n" 
            end
        end
    end
    sth.finish
end

begin
    dbh = DBI.connect('DBI:SQLAnywhere:demo', 'DBA', 'sql')
    db_query(dbh, "SELECT * FROM Products")
rescue DBI::DatabaseError => e
    puts "An error occurred"
    puts "Error code: #{e.err}"
    puts "Error message: #{e.errstr}"
    puts "Error SQLSTATE: #{e.state}"
ensure
    dbh.disconnect if dbh
end

Die ersten paar Zeilen der Ausgabe, die angezeigt werden, finden Sie untenstehend.

# of Fields:  8

ID=300
Name=Tee Shirt
Description=Tank Top
Size=Small
Color=White
Quantity=28
UnitPrice=9.00

ID=301
Name=Tee Shirt
Description=V-neck
Size=Medium
Color=Orange
Quantity=54
UnitPrice=14.00

Es ist wichtig, "finish" aufzurufen, um das Anweisungs-Handle freizugeben, wenn Sie fertig sind. Wenn Sie dies nicht tun, erhalten Sie möglicherweise einen Fehler wie den folgenden:

Resource governor for 'prepared statements' exceeded

Um Handle-Leaks zu erkennen, begrenzt der SQL Anywhere-Datenbankserver standardmäßig die Anzahl von Cursorn und vorbereiteten Anweisungen auf maximal 50 pro Verbindung. Der Ressourcenwächter generiert automatisch einen Fehler, wenn diese Grenzwerte überschritten werden. Wenn dieser Fehler auftritt, suchen Sie nach nicht entfernten Anweisungshandles. Verwenden Sie prepare_cached mit Bedacht, da die Anweisungshandles nicht entfernt werden.

Erforderlichenfalls können Sie diese Grenzwerte ändern, indem Sie die Optionen max_cursor_count und max_statement_count definieren. Weitere Hinweise finden Sie unter max_cursor_count-Option [Datenbank] und max_statement_count-Option [Datenbank].

Zeilen einfügen

Zum Einfügen von Zeilen wird ein Handle für eine offene Verbindung benötigt. Die einfachste Methode, Zeilen einzufügen, besteht darin, eine parametrisierte INSERT-Anweisung zu verwenden, in der Fragezeichen als Platzhalter für Werte eingesetzt werden. Die Anweisung wird erst vorbereitet und dann pro neuer Zeile ausgeführt. Die neuen Zeilenwerte werden als Parameter an die execute-Methode übergeben.

require 'dbi'

def db_query( dbh, sql )
    sth = dbh.execute(sql)
    print "# of Fields:  #{sth.column_names.size}\n"
    sth.fetch do |row|
        print "\n"
        sth.column_info.each_with_index do |info, i|
            unless info["type_name"] == "LONG VARBINARY"
                print "#{info["name"]}=#{row[i]}\n" 
            end
        end
    end
    sth.finish
end

def db_insert( dbh, rows )
    sql = "INSERT INTO Customers (ID, GivenName, Surname,
                Street, City, State, Country, PostalCode,
                Phone, CompanyName)
           VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
    sth = dbh.prepare(sql);
    rows.each do |row|
        sth.execute(row[0],row[1],row[2],row[3],row[4],
                    row[5],row[6],row[7],row[8],row[9])
    end
end

begin
    dbh = DBI.connect('DBI:SQLAnywhere:demo', 'DBA', 'sql')
    rows = [
        [801,'Alex','Alt','5 Blue Ave','New York','NY','USA',
            '10012','5185553434','BXM'],
        [802,'Zach','Zed','82 Fair St','New York','NY','USA',
            '10033','5185552234','Zap']
       ]
    db_insert(dbh, rows)
    dbh.commit
    db_query(dbh, "SELECT * FROM Customers WHERE ID > 800")
rescue DBI::DatabaseError => e
    puts "An error occurred"
    puts "Error code: #{e.err}"
    puts "Error message: #{e.errstr}"
    puts "Error SQLSTATE: #{e.state}"
ensure
    dbh.disconnect if dbh
end