2

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 から値を取得する方法は?

4

1 に答える 1