ResultSet は DB操作の結果を保持するクラスである。 文オブジェクトが一つ所有しており、execute を行うと更新される。
class IResultSet: public nine::Sharable
{
public:
virtual Connection getConnection() = 0;
virtual int getUpdateCount() = 0; // DDLなどカウントの無い場合は 0. エラーの場合は負。
virtual void close() = 0;
virtual bool next() = 0;
virtual int getRow() = 0; // 1-base
virtual int getColumnCount() = 0;
virtual bool getBool(int index, bool* value) = 0; //BOOL
virtual bool getUInt8(int index, uint8_t* value) = 0; //TINYINT
virtual bool getInt16(int index, int16_t* value) = 0; //SMALLINT
virtual bool getInt32(int index, int32_t* value) = 0; //INTEGER
virtual bool getInt64(int index, int64_t* value) = 0; //BIGINT
virtual bool getFloat32(int index, float* value) = 0; //REAL
virtual bool getFloat64(int index, double* value) = 0; //DOUBLE
virtual bool getString(int index, dbi_string* value) = 0; //VARCHAR(n)
virtual bool getDate(int index, Date* value) = 0; //DATE
virtual bool getTime(int index, Time* value) = 0; //TIME
virtual bool getTimestamp(int index, Timestamp* value) = 0; //TIMESTAMP
virtual TypeWarning getLastWarning() const = 0;
virtual bool isError() const = 0;
virtual const char* getSqlState() const = 0;
virtual int getDriverResultCode() const = 0;
virtual const char* getDriverErrorMessage() const = 0;
};
select の結果は複数行から構成される。 複数行を扱うため、ResultSet は「現在行」という状態を持っている。 各結果取得関数は現在行に対して動作することになる。
現在の行番号を得るには getRow() 関数を使う。有効な行番号は 1 以降である。 初期状態は特別な 0 行目であり、この状態では値を取得することができない。
次の行へ移るには next() を使う。 戻り値が真ならば、次の行を利用可能である。
rs = stmt.executeQuery(...);
while (rs->next()) {
...
}
現在行のフィールドを得るには、各 getXXX(index, value) 関数を使う。 XXX の部分は型名であり、その型で値を受け取る。
要求型とフィールド型が異なっていた場合、可能ならば変換されるが、不可能ならばエラーとなる。 詳細は次節で説明する。
rs = stmt.executeQuery("select now()");
rs->next();
nine::dbi::Timestamp ts;
rs->getTimestamp(1, &ts);
printf("%d-%d-%d %d:%d:%d\n", ts.getYear(), ts.getMonth(), ts.getDay(), ...);
nine::dbi::dbi_string s;
rs->getRawString(1, &s);
printf("%s\n", s.c_str());
ResultSet の get 関数で値を受け取る場合に、データベース側の型とアプリケーション側の型が異なっていた場合、可能ならば変換される。
エラーを示すいくつかの関数が提供されている。
基本は isError() であり、これは execute の結果がエラーであるかどうかを返す。
rs = stmt.executeQuery("seleect * from tbl")
は、seleect という命令文が間違っているため、
rs->isError()は真になる。
エラーの内容は、getSqlState(), getDriverResultCode(), getDriverErrorMessage() で得られる。
getSqlState() は SQL92/SQL99 で定義された標準規格であり、各 DBMS でコード体系を使えるようになっている。ただし、具体的なエラーをどのコードに割り当てるかは各DBMS依存なので、詳細は各 DBMS のドキュメントを参照する必要がある。
DriverResultCode() は、DBMS 固有の結果コードを返し、DriverErrorMessage() は、DBMS 固有の結果メッセージを返す。