A higher level ODBC database wrapper.
This is the same interface that is implemented for other databases.
This has NOT yet been (extensively) tested against ODBC drivers for Teradata, Oracle, Sybase, MSSqlvSvr, et. al. databases.
Currently all queries are ANSI calls, not Unicode.
See also: db_postgres, db_sqlite, db_mysql.
All db_*
modules support the same form of parameter substitution. That is, using the ?
(question mark) to signify the place where a value should be placed. For example:
sql"INSERT INTO myTable (colA, colB, colC) VALUES (?, ?, ?)"
import db_odbc var db = open("localhost", "user", "password", "dbname") db.close()
db.exec(sql"DROP TABLE IF EXISTS myTable") db.exec(sql("""CREATE TABLE myTable ( id integer, name varchar(50) not null)"""))
db.exec(sql"INSERT INTO myTable (id, name) VALUES (0, ?)", "Andreas")
import db_odbc, math var theDb = open("localhost", "nim", "nim", "test") theDb.exec(sql"Drop table if exists myTestTbl") theDb.exec(sql("create table myTestTbl (" & " Id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, " & " Name VARCHAR(50) NOT NULL, " & " i INT(11), " & " f DECIMAL(18,10))")) theDb.exec(sql"START TRANSACTION") for i in 1..1000: theDb.exec(sql"INSERT INTO myTestTbl (name,i,f) VALUES (?,?,?)", "Item#" & $i, i, sqrt(i.float)) theDb.exec(sql"COMMIT") for x in theDb.fastRows(sql"select * from myTestTbl"): echo x let id = theDb.tryInsertId(sql"INSERT INTO myTestTbl (name,i,f) VALUES (?,?,?)", "Item#1001", 1001, sqrt(1001.0)) echo "Inserted item: ", theDb.getValue(sql"SELECT name FROM myTestTbl WHERE id=?", id) theDb.close()
DbConn = OdbcConnTyp
Row = seq[string]
InstantRow = tuple[row: seq[string], len: int]
proc dbError(db: var DbConn) {...}{.tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
proc dbQuote(s: string): string {...}{.noSideEffect, raises: [], tags: [].}
proc tryExec(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): bool {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [].}
proc exec(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]) {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
proc `[]`(row: InstantRow; col: int): string {...}{.inline, raises: [], tags: [].}
proc len(row: InstantRow): int {...}{.inline, raises: [], tags: [].}
proc getRow(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): Row {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
proc getAllRows(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): seq[Row] {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
proc getValue(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): string {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [].}
proc tryInsertId(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): int64 {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [].}
proc insertId(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): int64 {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
proc execAffectedRows(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): int64 {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
proc close(db: var DbConn) {...}{.tags: [WriteDbEffect], raises: [].}
proc open(connection, user, password, database: string): DbConn {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
Opens a database connection.
Raises EDb if the connection could not be established.
Currently the database parameter is ignored, but included to match open()
in the other db_xxxxx library modules.
proc setEncoding(connection: DbConn; encoding: string): bool {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
Currently not implemented for ODBC.
Sets the encoding of a database connection, returns true for success, false for failure. result = set_character_set(connection, encoding) == 0
iterator fastRows(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): Row {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
Executes the query and iterates over the result dataset.
This is very fast, but potentially dangerous. Use this iterator only if you require ALL the rows.
Breaking the fastRows() iterator during a loop may cause a driver error for subsequenct queries
Rows are retrieved from the server at each iteration.
iterator instantRows(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): InstantRow {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
iterator rows(db: var DbConn; query: SqlQuery; args: varargs[string, `$`]): Row {...}{. tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].}
Same as fastRows, but slower and safe.
This retrieves ALL rows into memory before iterating through the rows. Large dataset queries will impact on memory usage.
© 2006–2018 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/db_odbc.html