blob: c673c4122ac046f6c2b7c7e02013adcbd3eed747 [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Introduction
2
3The 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
5This page provides example usage patterns.
6
7# Database driver
8
9The database/sql package must be used in conjunction with a database driver.
10See http://golang.org/s/sqldrivers for a list of drivers.
11
12The documentation below assumes a driver has been imported.
13
14# Connecting to a database
15
16Open is used to create a database handle:
17
18```
19db, err := sql.Open(driver, dataSourceName)
20```
21
22Where driver specifies a database driver and dataSourceName
23specifies database-specific connection information
24such as database name and authentication credentials.
25
Konstantin Kulikovc7758eb2015-08-08 12:48:54 +030026Note 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```
29if err := db.Ping(); err != nil {
30 log.Fatal(err)
31}
32```
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110033
34After use, the database is closed using Close.
35
36# Executing queries
37
38Exec is used for queries where no rows are returned:
39
40```
41result, err := db.Exec(
gordonklaus0be401b2015-05-31 19:28:26 +020042 "INSERT INTO users (name, age) VALUES ($1, $2)",
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110043 "gopher",
44 27,
45)
46```
47
48Where result contains the last insert ID and number of
49rows affected. The availability of these values is dependent on
50the database driver.
51
52Query is used for retrieval:
53
54```
gordonklaus0be401b2015-05-31 19:28:26 +020055rows, err := db.Query("SELECT name FROM users WHERE age = $1", age)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110056if err != nil {
57 log.Fatal(err)
58}
59for rows.Next() {
60 var name string
61 if err := rows.Scan(&name); err != nil {
62 log.Fatal(err)
63 }
64 fmt.Printf("%s is %d\n", name, age)
65}
66if err := rows.Err(); err != nil {
67 log.Fatal(err)
68}
69```
70
71QueryRow is used where only a single row is expected:
72
73```
74var age int64
gordonklaus0be401b2015-05-31 19:28:26 +020075row := db.QueryRow("SELECT age FROM users WHERE name = $1", name)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110076err := row.Scan(&age)
77```
78
79Prepared statements can be created with Prepare:
80
81```
82age := 27
gordonklaus0be401b2015-05-31 19:28:26 +020083stmt, err := db.Prepare("SELECT name FROM users WHERE age = $1")
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110084if err != nil {
85 log.Fatal(err)
86}
87rows, err := stmt.Query(age)
88// process rows
89```
90
91Exec, Query and QueryRow can be called on statements. After use, a
92statement should be closed with Close.
93
94# Transactions
95
96Transactions are started with Begin:
97
98```
99tx, err := db.Begin()
100if err != nil {
101 log.Fatal(err)
102}
103```
104
105The Exec, Query, QueryRow and Prepare functions already covered can be
106used in a transaction.
107
108A transaction must end with a call to Commit or Rollback.
109
110# Dealing with NULL
111
112If a database column is nullable, one of the types supporting null values should be passed to Scan.
113
114For example, if the name column in the names table is nullable:
115
116```
117var name NullString
gordonklaus0be401b2015-05-31 19:28:26 +0200118err := db.QueryRow("SELECT name FROM names WHERE id = $1", id).Scan(&name)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100119...
120if name.Valid {
121 // use name.String
122} else {
123 // value is NULL
124}
125```
126
127Only NullBool, NullFloat64, NullInt64 and NullString are implemented in
128database/sql. Implementations of database-specific null types are left
129to the database driver.