Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 1 | # Introduction |
| 2 | |
| 3 | The database/sql package provides a generic interface around SQL (or SQL-like) databases. See the [official documentation](http://golang.org/pkg/database/sql/) for details. |
| 4 | |
| 5 | This page provides example usage patterns. |
| 6 | |
| 7 | # Database driver |
| 8 | |
| 9 | The database/sql package must be used in conjunction with a database driver. |
| 10 | See http://golang.org/s/sqldrivers for a list of drivers. |
| 11 | |
| 12 | The documentation below assumes a driver has been imported. |
| 13 | |
| 14 | # Connecting to a database |
| 15 | |
| 16 | Open is used to create a database handle: |
| 17 | |
| 18 | ``` |
| 19 | db, err := sql.Open(driver, dataSourceName) |
| 20 | ``` |
| 21 | |
| 22 | Where driver specifies a database driver and dataSourceName |
| 23 | specifies database-specific connection information |
| 24 | such as database name and authentication credentials. |
| 25 | |
| 26 | Note that Open does not directly open a database connection: this is deferred until a query is made. To verify that a connection can be made before making a query, use the Ping function. |
| 27 | |
| 28 | After use, the database is closed using Close. |
| 29 | |
| 30 | # Executing queries |
| 31 | |
| 32 | Exec is used for queries where no rows are returned: |
| 33 | |
| 34 | ``` |
| 35 | result, err := db.Exec( |
| 36 | "INSERT INTO users (name, age) VALUES (?, ?)", |
| 37 | "gopher", |
| 38 | 27, |
| 39 | ) |
| 40 | ``` |
| 41 | |
| 42 | Where result contains the last insert ID and number of |
| 43 | rows affected. The availability of these values is dependent on |
| 44 | the database driver. |
| 45 | |
| 46 | Query is used for retrieval: |
| 47 | |
| 48 | ``` |
| 49 | rows, err := db.Query("SELECT name FROM users WHERE age = ?", age) |
| 50 | if err != nil { |
| 51 | log.Fatal(err) |
| 52 | } |
| 53 | for rows.Next() { |
| 54 | var name string |
| 55 | if err := rows.Scan(&name); err != nil { |
| 56 | log.Fatal(err) |
| 57 | } |
| 58 | fmt.Printf("%s is %d\n", name, age) |
| 59 | } |
| 60 | if err := rows.Err(); err != nil { |
| 61 | log.Fatal(err) |
| 62 | } |
| 63 | ``` |
| 64 | |
| 65 | QueryRow is used where only a single row is expected: |
| 66 | |
| 67 | ``` |
| 68 | var age int64 |
| 69 | row := db.QueryRow("SELECT age FROM users WHERE name = ?", name) |
| 70 | err := row.Scan(&age) |
| 71 | ``` |
| 72 | |
| 73 | Prepared statements can be created with Prepare: |
| 74 | |
| 75 | ``` |
| 76 | age := 27 |
| 77 | stmt, err := db.Prepare("SELECT name FROM users WHERE age = ?") |
| 78 | if err != nil { |
| 79 | log.Fatal(err) |
| 80 | } |
| 81 | rows, err := stmt.Query(age) |
| 82 | // process rows |
| 83 | ``` |
| 84 | |
| 85 | Exec, Query and QueryRow can be called on statements. After use, a |
| 86 | statement should be closed with Close. |
| 87 | |
| 88 | # Transactions |
| 89 | |
| 90 | Transactions are started with Begin: |
| 91 | |
| 92 | ``` |
| 93 | tx, err := db.Begin() |
| 94 | if err != nil { |
| 95 | log.Fatal(err) |
| 96 | } |
| 97 | ``` |
| 98 | |
| 99 | The Exec, Query, QueryRow and Prepare functions already covered can be |
| 100 | used in a transaction. |
| 101 | |
| 102 | A transaction must end with a call to Commit or Rollback. |
| 103 | |
| 104 | # Dealing with NULL |
| 105 | |
| 106 | If a database column is nullable, one of the types supporting null values should be passed to Scan. |
| 107 | |
| 108 | For example, if the name column in the names table is nullable: |
| 109 | |
| 110 | ``` |
| 111 | var name NullString |
| 112 | err := db.QueryRow("SELECT name FROM names WHERE id = ?", id).Scan(&name) |
| 113 | ... |
| 114 | if name.Valid { |
| 115 | // use name.String |
| 116 | } else { |
| 117 | // value is NULL |
| 118 | } |
| 119 | ``` |
| 120 | |
| 121 | Only NullBool, NullFloat64, NullInt64 and NullString are implemented in |
| 122 | database/sql. Implementations of database-specific null types are left |
| 123 | to the database driver. |