go-oci8 ( https://github.com/mattn/go-oci8 ) ドライバーで sqlx ( https://github.com/jmoiron/sqlx ) を使用して、go アプリケーションから Oracle データベースに 2 つのレコードを挿入する必要があります。2 番目のレコードは、外部キーによって前のレコードを参照します。そのため、2 番目のレコードを挿入する前に、最初のレコードの主キーが必要です (最初のテーブルの挿入トリガーの前にシーケンスから割り当てられます)。
だから私は最後に挿入されたIDを取得するために実験しました:
create table t(x int primary key);
create sequence x_seq;
LastInsertId が失敗しました:
import(
"fmt"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-oci8"
)
func main(){
db, err := sqlx.Connect("oci8", "integr/integr@localhost:49161/xe")
if err != nil {
fmt.Println(err)
}
sql := "insert into t values(x_seq.nextval)"
r, err := db.Exec(sql)
if err != nil {
fmt.Println(err)
}
fmt.Println(r.RowsAffected())
fmt.Println(r.LastInsertId())
}
出力:
1 <nil>
0 LastInsertId not supported
次に、レコードを挿入して主キーを返すストアド関数を作成しようとしました。
create function f(x int) return int as
v int;
begin
insert into t values(x)
returning x into v;
return v;
end;
しかし、その結果を得る方法を見つけることができませんでした。PostgreSQL スタイルの選択が失敗します:
SQL> select f(9) from dual;
select f(9) from dual
*
ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "INTEGR.F", line 1
また、OCI8 スタイルの変数バインディングは機能しません。
package main
import(
"fmt"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-oci8"
)
func main(){
db, err := sqlx.Connect("oci8", "integr/integr@localhost:49161/xe")
if err != nil {
fmt.Println(err)
}
sql := sqlx.Rebind(sqlx.NAMED,"begin ? := f(?); end;")
var a int
_, err = db.Exec(sql, a, 333)
if err != nil {
fmt.Println(err)
}
fmt.Println(sql)
fmt.Println(a)
}
出力:
begin :arg1 := f(:arg2); end;
0
最後に挿入された ID を取得する方法、または Go の格納された関数から Oracle から値を取得する方法は?