PostgreSQL 與 Postmodern 的簡單使用
Postmodern 是一個連線關聯式資料庫 PostgreSQL 的庫。它提供了對 PostgreSQL 的幾種訪問級別,從表示為字串或列表的 SQL 查詢到物件關係對映的執行。
可以使用以下 SQL 語句建立以下示例中使用的資料庫:
create table employees
(empid integer not null primary key,
name text not null,
birthdate date not null,
skills text[] not null);
insert into employees (empid, name, birthdate, skills) values
(1, 'John Orange', '1991-07-26', '{C, Java}'),
(2, 'Mary Red', '1989-04-14', '{C, Common Lisp, Hunchentoot}'),
(3, 'Ron Blue', '1974-01-17', '{JavaScript, Common Lisp}'),
(4, 'Lucy Green', '1968-02-02', '{Java, JavaScript}');
第一個示例顯示返回關係的簡單查詢的結果:
CL-USER> (ql:quickload "postmodern") ; load the system postmodern (nickname: pomo)
("postmodern")
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(pomo:query "select name, skills from employees")))
(("John Orange" #("C" "Java")) ; output manually edited!
("Mary Red" #("C" "Common Lisp" "Hunchentoot"))
("Ron Blue" #("JavaScript" "Common Lisp"))
("Lucy Green" #("Java" "JavaScript")))
4 ; the second value is the size of the result
請注意,結果可以作為 alist 或 plists 的列表返回,將可選引數:alists
或:plists
新增到查詢函式中。
query
的替代方法是 doquery
,用於迭代查詢結果。它的引數是 query (&rest names) &body body
,其中名稱繫結到每次迭代時行中的值:
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(format t "The employees that knows Java are:~%")
(pomo:doquery "select empid, name from employees where skills @> '{Java}'" (i n)
(format t "~a (id = ~a)~%" n i))))
The employees that knows Java are:
John Orange (id = 1)
Lucy Green (id = 4)
NIL
2
當查詢需要引數時,可以使用預準備語句:
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(funcall
(pomo:prepare "select name, skills from employees where skills @> $1")
#("Common Lisp")))) ; find employees with skills including Common Lisp
(("Mary Red" #("C" "Common Lisp" "Hunchentoot"))
("Ron Blue" #("JavaScript" "Common Lisp")))
2
函式 prepare
接收帶佔位符 $1
,$2
等的查詢,並返回一個新函式,該函式需要每個佔位符一個引數,並在使用正確數量的引數呼叫時執行查詢。
在更新的情況下,函式 exec
返回修改的元組數(兩個 DDL 語句包含在事務中):
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(pomo:ensure-transaction
(values
(pomo:execute "alter table employees add column salary integer")
(pomo:execute "update employees set salary =
case when skills @> '{Common Lisp}'
then 100000 else 50000 end")))))
0
4
除了將 SQL 查詢編寫為字串之外,還可以使用關鍵字,符號和常量列表,其語法與 lisp(S-SQL)相似:
CL-USER> (let ((parameters '("database" "dbuser" "dbpass" "localhost")))
(pomo:with-connection parameters
(pomo:query (:select 'name :from 'employees :where (:> 'salary 60000)))))
(("Mary Red") ("Ron Blue"))
2