or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connection.mdcopy-operations.mdindex.mdprepared-statements.mdqueries.md

prepared-statements.mddocs/

0

# Prepared Statements

1

2

Prepared statement functionality for optimized repeated query execution with proper parameter binding and both async and sync interfaces.

3

4

## Capabilities

5

6

### Asynchronous Statement Preparation

7

8

Prepare a named statement for later execution.

9

10

```javascript { .api }

11

/**

12

* Prepare a named statement asynchronously

13

* @param statementName - Unique name for the prepared statement

14

* @param text - SQL query text with $1, $2, etc. placeholders

15

* @param nParams - Number of parameters in the query

16

* @param callback - Callback function called when preparation completes

17

*/

18

client.prepare(

19

statementName: string,

20

text: string,

21

nParams: number,

22

callback: (err: Error | null) => void

23

): void;

24

```

25

26

**Usage Examples:**

27

28

```javascript

29

const client = new Client();

30

client.connectSync();

31

32

// Prepare a simple select statement

33

client.prepare(

34

'get_user_by_id',

35

'SELECT name, email FROM users WHERE id = $1',

36

1,

37

function(err) {

38

if (err) throw err;

39

console.log('Statement prepared successfully');

40

}

41

);

42

43

// Prepare an insert statement

44

client.prepare(

45

'insert_user',

46

'INSERT INTO users (name, email, age) VALUES ($1, $2, $3) RETURNING id',

47

3,

48

function(err) {

49

if (err) throw err;

50

console.log('Insert statement prepared');

51

}

52

);

53

54

// Prepare a complex query

55

client.prepare(

56

'search_users',

57

'SELECT * FROM users WHERE age BETWEEN $1 AND $2 AND city = $3 ORDER BY name',

58

3,

59

function(err) {

60

if (err) throw err;

61

console.log('Search statement prepared');

62

}

63

);

64

```

65

66

### Synchronous Statement Preparation

67

68

Prepare a named statement synchronously.

69

70

```javascript { .api }

71

/**

72

* Prepare a named statement synchronously

73

* @param statementName - Unique name for the prepared statement

74

* @param text - SQL query text with $1, $2, etc. placeholders

75

* @param nParams - Number of parameters in the query

76

* @throws Error if preparation fails

77

*/

78

client.prepareSync(

79

statementName: string,

80

text: string,

81

nParams: number

82

): void;

83

```

84

85

**Usage Examples:**

86

87

```javascript

88

const client = new Client();

89

client.connectSync();

90

91

try {

92

// Prepare statements synchronously

93

client.prepareSync(

94

'get_user_by_id',

95

'SELECT name, email FROM users WHERE id = $1',

96

1

97

);

98

99

client.prepareSync(

100

'update_user_age',

101

'UPDATE users SET age = $1 WHERE id = $2',

102

2

103

);

104

105

console.log('All statements prepared successfully');

106

} catch (err) {

107

console.error('Statement preparation failed:', err.message);

108

}

109

```

110

111

### Asynchronous Statement Execution

112

113

Execute a previously prepared statement with parameters.

114

115

```javascript { .api }

116

/**

117

* Execute a prepared statement asynchronously

118

* @param statementName - Name of the prepared statement

119

* @param parameters - Array of parameter values

120

* @param callback - Callback function receiving results

121

*/

122

client.execute(

123

statementName: string,

124

parameters: any[],

125

callback: (err: Error | null, rows: any[], results?: any) => void

126

): void;

127

```

128

129

**Usage Examples:**

130

131

```javascript

132

const client = new Client();

133

client.connectSync();

134

135

// Prepare a statement first

136

client.prepareSync(

137

'get_user_by_id',

138

'SELECT name, email FROM users WHERE id = $1',

139

1

140

);

141

142

// Execute the prepared statement multiple times

143

client.execute('get_user_by_id', [1], function(err, rows) {

144

if (err) throw err;

145

console.log('User 1:', rows[0]);

146

});

147

148

client.execute('get_user_by_id', [2], function(err, rows) {

149

if (err) throw err;

150

console.log('User 2:', rows[0]);

151

});

152

153

// Execute with different parameter types

154

client.prepareSync(

155

'search_users',

156

'SELECT * FROM users WHERE age > $1 AND active = $2',

157

2

158

);

159

160

client.execute('search_users', [25, true], function(err, rows) {

161

if (err) throw err;

162

console.log('Active users over 25:', rows);

163

});

164

```

165

166

### Synchronous Statement Execution

167

168

Execute a previously prepared statement synchronously.

169

170

```javascript { .api }

171

/**

172

* Execute a prepared statement synchronously

173

* @param statementName - Name of the prepared statement

174

* @param parameters - Array of parameter values

175

* @returns Array of result rows

176

* @throws Error if execution fails

177

*/

178

client.executeSync(statementName: string, parameters: any[]): any[];

179

```

180

181

**Usage Examples:**

182

183

```javascript

184

const client = new Client();

185

client.connectSync();

186

187

// Prepare statements

188

client.prepareSync(

189

'get_user_by_id',

190

'SELECT name, email FROM users WHERE id = $1',

191

1

192

);

193

194

client.prepareSync(

195

'insert_user',

196

'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id',

197

2

198

);

199

200

try {

201

// Execute select statement

202

const user = client.executeSync('get_user_by_id', [1]);

203

console.log('Retrieved user:', user[0]);

204

205

// Execute insert statement

206

const insertResult = client.executeSync('insert_user', ['Alice', 'alice@example.com']);

207

console.log('New user ID:', insertResult[0].id);

208

209

// Execute multiple times with different parameters

210

const users = [

211

['Bob', 'bob@example.com'],

212

['Charlie', 'charlie@example.com']

213

];

214

215

users.forEach(userData => {

216

const result = client.executeSync('insert_user', userData);

217

console.log('Inserted user ID:', result[0].id);

218

});

219

220

} catch (err) {

221

console.error('Statement execution failed:', err.message);

222

}

223

```

224

225

### Complete Prepared Statement Workflow

226

227

A complete example showing the full prepare-execute-reuse pattern:

228

229

```javascript

230

const Client = require('pg-native');

231

232

const client = new Client();

233

client.connectSync();

234

235

// Prepare multiple statements for a user management system

236

client.prepareSync(

237

'create_user',

238

'INSERT INTO users (name, email, age) VALUES ($1, $2, $3) RETURNING id, created_at',

239

3

240

);

241

242

client.prepareSync(

243

'get_user',

244

'SELECT id, name, email, age, created_at FROM users WHERE id = $1',

245

1

246

);

247

248

client.prepareSync(

249

'update_user',

250

'UPDATE users SET name = $1, email = $2, age = $3 WHERE id = $4 RETURNING *',

251

4

252

);

253

254

client.prepareSync(

255

'delete_user',

256

'DELETE FROM users WHERE id = $1',

257

1

258

);

259

260

try {

261

// Create a new user

262

const newUser = client.executeSync('create_user', ['John Doe', 'john@example.com', 30]);

263

const userId = newUser[0].id;

264

console.log('Created user:', newUser[0]);

265

266

// Retrieve the user

267

const retrievedUser = client.executeSync('get_user', [userId]);

268

console.log('Retrieved user:', retrievedUser[0]);

269

270

// Update the user

271

const updatedUser = client.executeSync('update_user', [

272

'John Smith',

273

'johnsmith@example.com',

274

31,

275

userId

276

]);

277

console.log('Updated user:', updatedUser[0]);

278

279

// Delete the user

280

client.executeSync('delete_user', [userId]);

281

console.log('User deleted');

282

283

} catch (err) {

284

console.error('Operation failed:', err.message);

285

} finally {

286

client.end();

287

}

288

```

289

290

## Performance Benefits

291

292

Prepared statements provide several advantages:

293

294

1. **Query Plan Caching**: PostgreSQL parses and plans the query once

295

2. **Parameter Binding**: Secure parameter substitution without string concatenation

296

3. **Reduced Network Traffic**: Statement name sent instead of full SQL text

297

4. **Type Safety**: PostgreSQL validates parameter types during preparation

298

299

## Best Practices

300

301

1. **Prepare once, execute many**: Ideal for queries executed multiple times

302

2. **Use meaningful names**: Choose descriptive statement names

303

3. **Match parameter counts**: Ensure `nParams` matches the actual placeholders

304

4. **Handle preparation errors**: Always check for preparation failures

305

5. **Clean resource usage**: Prepared statements persist for the connection lifetime