clsqlの勉強 その1
clsqlをいじってみる。
(require :clsql) ;;クエリ (clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) (pprint (clsql-sys:query "select * from tb0" :database con))) ;;prepared statementを使用 (clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) (let ((stmt (clsql-sys:prepare-sql "select * from tb0 where id = ?" '(:int) :database con))) (clsql-sys:bind-parameter stmt 1 1) (let ((r (clsql-sys:run-prepared-sql stmt))) (pprint r)))) ;;prepared statementを使用(文字列) (stirng n)ではダメで(varchar n)ならいけた (clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) (let ((stmt (clsql-sys:prepare-sql "select * from tb0 where data1 = ?" '((:varchar 10)) :database con))) (clsql-sys:bind-parameter stmt 1 "更新") (let ((r (clsql-sys:run-prepared-sql stmt))) (pprint r)))) ;;prepaerd statementによる更新(うまくいかない) ;;戻りのresultsetがないときにうまくいっていない?? ;; (clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) ;; (let ((stmt (clsql-sys:prepare-sql "insert into tb0 values (?,?,?)" '(:int (:varchar 20) (:varchar 20)) :database con))) ;; (clsql-sys:bind-parameter stmt 1 5) ;; (clsql-sys:bind-parameter stmt 2 "日本語") ;; (clsql-sys:bind-parameter stmt 3 "日本語") ;; (clsql-sys:database-run-prepared stmt) ;; nil))) ;; While accessing database #<POSTGRESQL-SOCKET-DATABASE localhost/xxx/xxx OPEN {1004E70461}> ;; with expression "EXECUTE CLSQL_PS_22 (5,'日本語','日本語')": ;; Error missing-result / Didn't receive result cursor for query. ;; has occurred. ;; [Condition of type CLSQL-SYS:SQL-DATABASE-DATA-ERROR] ;;DAO定義 (clsql:def-view-class test0() ((test0-id :accessor test0-id :initarg :test0-id :type integer :db-kind :key :db-constraints (:not-null :unique)) (test0-string :accessor test0-string :initarg :test0-string :type (clsql:varchar 10)) (test0-bool :accessor test0-bool :initarg :test0-bool :type boolean))) ;;テーブルの作成 (clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) (ignore-errors (clsql:create-view-from-class 'test0 :database con))) ;;insert ;; (clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) ;; (let ((test0 (make-instance 'test0 ;; :test0-id 0 ;; :test0-string "初期値0" ;; :test0-bool nil))) ;; (clsql:update-records-from-instance test0 :database con)) ;; (let ((test0 (make-instance 'test0 ;; :test0-id 1 ;; :test0-string "初期値1" ;; :test0-bool nil))) ;; (clsql:update-records-from-instance test0 :database con))) ;;select (clsql:file-enable-sql-reader-syntax) (clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) (let ((result (clsql:select 'test0 :where [or [= [slot-value 'test0 'test0-id] 0] [= [slot-value 'test0 'test0-id] 1]] :database con :flatp t))) (mapcar #'(lambda (o) (pprint (test0-id o)) (pprint (test0-string o))) result))) ;;insert ;;'を入れても大丈夫だった。 ;; (clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) ;; (let ((test0 (make-instance 'test0 ;; :test0-id 2 ;; :test0-string "aaa'bbb" ;; :test0-bool nil))) ;; (clsql:update-records-from-instance test0 :database con))) ;;更新 (clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) (let ((result (clsql:select 'test0 :where [= [slot-value 'test0 'test0-id] 0] :database con :flatp t))) (mapcar #'(lambda (o) (pprint (test0-id o)) (pprint (test0-string o)) (setf (slot-value o 'test0-string) "更新'@_\更新") (clsql:update-records-from-instance o :database con)) result))) ;;クエリ 型付けして返す。でもbooleanがうまくいってない。 (clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket) (pprint (clsql-sys:query "select * from test0" :database con :flatp nil :result-types '(:int (:varchar 10) :boolean))))
プリペアドステートメントでクエリはできるんだけど、更新がうまくいかない。
def-view-classでORMを使ったときもプリペアドステートメントは使っていないみた。(ポスグレのログで確認)
:result-typesで型を指定してみたんだけど、booleanと書いても文字列で戻ってきちゃう。謎。