WeHelp
PostgreSQL 是一套免費、開源的強大物件關聯式資料庫管理系統,適合處理複雜的結構化資料與高負載應用程式。
  1. PostgreSQL 下載安裝
  2. 啟動、連線測試
  3. Database 管理
  4. Schema 管理
  5. SQL 資料表管理
  6. SQL 資料管理
  7. SQL 資料取得、篩選
  8. 欄位的資料型態
  9. 資料交易簡介、操作
  10. 使用者管理
  11. Python 程式連線
  12. Node.js 程式連線
  13. C# 程式連線
Node.js 程式連線
在 Node.js 中,最常用的 PostgreSQL 驅動程式是 [`pg`](https://www.npmjs.com/package/pg)。基本流程如下: 1. 安裝 PostgreSQL 驅動程式 2. 建立資料庫連線 3. 執行 SQL 4. 讀取查詢結果 5. 關閉連線或釋放連線 --- ## 1. 安裝 `pg` 在 Node.js 專案目錄執行: ```bash npm install pg ``` 如果使用 ES Module,可在 `package.json` 加上: ```json { "type": "module" } ``` --- ## 2. 建立 PostgreSQL 連線 ### 方法一:使用單一連線 ```js const { Client } = require('pg'); const client = new Client({ host: 'localhost', port: 5432, user: 'postgres', password: 'your_password', database: 'mydb' }); async function main() { try { await client.connect(); console.log('已連線到 PostgreSQL'); await client.end(); } catch (error) { console.error('連線失敗:', error); } } main(); ``` 如果使用 ES Module: ```js import pg from 'pg'; const { Client } = pg; const client = new Client({ host: 'localhost', port: 5432, user: 'postgres', password: 'your_password', database: 'mydb' }); ``` --- ## 3. 使用連線池 在 Web API 或長時間執行的 Node.js 程式中,通常建議使用 `Pool`,它可以重複使用多個資料庫連線。 ```js const { Pool } = require('pg'); const pool = new Pool({ host: 'localhost', port: 5432, user: 'postgres', password: 'your_password', database: 'mydb', max: 10 }); ``` 也可以使用連線字串: ```js const pool = new Pool({ connectionString: 'postgresql://postgres:your_password@localhost:5432/mydb' }); ``` 正式環境通常會把連線資訊放在環境變數中: ```js const pool = new Pool({ connectionString: process.env.DATABASE_URL }); ``` 例如 `.env`: ```env DATABASE_URL=postgresql://postgres:your_password@localhost:5432/mydb ``` 若要讀取 `.env`,可安裝: ```bash npm install dotenv ``` 程式中: ```js require('dotenv').config(); const { Pool } = require('pg'); const pool = new Pool({ connectionString: process.env.DATABASE_URL }); ``` --- # 4. 執行 SQL 指令 ## 查詢資料:`SELECT` 假設資料表如下: ```sql CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(200) UNIQUE NOT NULL ); ``` Node.js 程式: ```js async function getUsers() { const result = await pool.query( 'SELECT id, name, email FROM users ORDER BY id' ); console.log(result.rows); } getUsers() .catch(console.error) .finally(() => pool.end()); ``` `result` 通常包含: ```js { rows: [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' } ], rowCount: 2, fields: [...] } ``` 最常使用的是: ```js result.rows ``` 以及: ```js result.rowCount ``` --- ## 5. 使用參數化查詢 不要直接把使用者輸入字串串接到 SQL 中: ```js // 不建議,可能造成 SQL Injection const name = req.query.name; await pool.query( `SELECT * FROM users WHERE name = '${name}'` ); ``` 應使用 PostgreSQL 的參數化查詢: ```js const name = 'Alice'; const result = await pool.query( 'SELECT id, name, email FROM users WHERE name = $1', [name] ); console.log(result.rows); ``` 多個參數: ```js const name = 'Alice'; const email = 'alice@example.com'; const result = await pool.query( 'SELECT * FROM users WHERE name = $1 AND email = $2', [name, email] ); ``` `$1`、`$2` 會由 `pg` 安全地代入參數。 --- # 6. 新增資料:`INSERT` ```js async function createUser(name, email) { const result = await pool.query( `INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id, name, email`, [name, email] ); return result.rows[0]; } createUser('Charlie', 'charlie@example.com') .then(user => { console.log('新增的使用者:', user); }) .catch(console.error) .finally(() => pool.end()); ``` `RETURNING` 可以取得剛新增的資料: ```js { id: 3, name: 'Charlie', email: 'charlie@example.com' } ``` --- # 7. 修改資料:`UPDATE` ```js async function updateUser(id, name, email) { const result = await pool.query( `UPDATE users SET name = $1, email = $2 WHERE id = $3 RETURNING id, name, email`, [name, email, id] ); return result.rows[0]; } const user = await updateUser( 1, 'Alice Wang', 'alice.wang@example.com' ); console.log(user); ``` 如果找不到指定的 `id`,可能會得到: ```js undefined ``` 可以先檢查: ```js if (result.rowCount === 0) { console.log('找不到資料'); } ``` --- # 8. 刪除資料:`DELETE` ```js async function deleteUser(id) { const result = await pool.query( 'DELETE FROM users WHERE id = $1', [id] ); return result.rowCount; } const deletedCount = await deleteUser(1); console.log(`刪除了 ${deletedCount} 筆資料`); ``` --- # 9. 完整範例 以下是一個可直接執行的 CommonJS 範例: ```js const { Pool } = require('pg'); const pool = new Pool({ host: 'localhost', port: 5432, user: 'postgres', password: 'your_password', database: 'mydb' }); async function main() { try { // 1. 新增資料 const insertResult = await pool.query( `INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *`, ['Alice', 'alice@example.com'] ); console.log('新增資料:', insertResult.rows[0]); // 2. 查詢資料 const selectResult = await pool.query( 'SELECT * FROM users WHERE email = $1', ['alice@example.com'] ); console.log('查詢結果:', selectResult.rows); // 3. 修改資料 const updateResult = await pool.query( `UPDATE users SET name = $1 WHERE email = $2 RETURNING *`, ['Alice Chen', 'alice@example.com'] ); console.log('修改結果:', updateResult.rows[0]); // 4. 刪除資料 const deleteResult = await pool.query( 'DELETE FROM users WHERE email = $1', ['alice@example.com'] ); console.log('刪除筆數:', deleteResult.rowCount); } catch (error) { console.error('資料庫操作失敗:', error); } finally { await pool.end(); } } main(); ``` --- # 10. 在 Web API 中取得資料 以 Express 為例: ```bash npm install express pg ``` ```js const express = require('express'); const { Pool } = require('pg'); const app = express(); app.use(express.json()); const pool = new Pool({ connectionString: process.env.DATABASE_URL }); app.get('/users', async (req, res) => { try { const result = await pool.query( 'SELECT id, name, email FROM users ORDER BY id' ); res.json(result.rows); } catch (error) { console.error(error); res.status(500).json({ error: '資料庫查詢失敗' }); } }); app.get('/users/:id', async (req, res) => { try { const result = await pool.query( 'SELECT id, name, email FROM users WHERE id = $1', [req.params.id] ); if (result.rowCount === 0) { return res.status(404).json({ error: '找不到使用者' }); } res.json(result.rows[0]); } catch (error) { console.error(error); res.status(500).json({ error: '資料庫查詢失敗' }); } }); app.listen(3000, () => { console.log('伺服器執行於 http://localhost:3000'); }); ``` 啟動後: ```bash node app.js ``` 瀏覽: ```text http://localhost:3000/users ``` 可能得到: ```json [ { "id": 1, "name": "Alice", "email": "alice@example.com" } ] ``` --- # 11. 交易 Transaction 如果多個 SQL 必須全部成功,應使用交易: ```js async function transferMoney(fromId, toId, amount) { const client = await pool.connect(); try { await client.query('BEGIN'); await client.query( `UPDATE accounts SET balance = balance - $1 WHERE id = $2`, [amount, fromId] ); await client.query( `UPDATE accounts SET balance = balance + $1 WHERE id = $2`, [amount, toId] ); await client.query('COMMIT'); } catch (error) { await client.query('ROLLBACK'); throw error; } finally { client.release(); } } ``` 使用連線池取得連線時,必須使用: ```js client.release(); ``` 而不是: ```js client.end(); ``` `pool.end()` 通常只在程式即將結束時呼叫。 --- ## 重點整理 ```js const result = await pool.query( 'SELECT * FROM users WHERE id = $1', [userId] ); const rows = result.rows; ``` 常見操作: | 操作 | SQL | Node.js 取得結果 | |---|---|---| | 查詢 | `SELECT` | `result.rows` | | 新增 | `INSERT` | 搭配 `RETURNING` 取得新增資料 | | 修改 | `UPDATE` | 搭配 `RETURNING` 取得修改後資料 | | 刪除 | `DELETE` | `result.rowCount` 取得刪除筆數 | 實務上建議: - 使用 `Pool` 管理連線 - 使用 `$1`、`$2` 參數化查詢 - 不要直接串接使用者輸入 - 連線密碼放在環境變數 - 非同步操作使用 `async/await` - 交易中使用 `BEGIN`、`COMMIT`、`ROLLBACK` - 使用完從連線池取得的連線後,要呼叫 `client.release()`
相關學習地圖、教學課程
Python 資料工程
從 0 開始,成為資料工程師的學習路徑。