Получить последний вставленный идентификатор (go + oracle)

Мне нужно вставить две записи в базу данных Oracle из моего приложения go с помощью sqlx (https://github.com/jmoiron/sqlx) с помощью go-oci8 (https://github.com/mattn/go-oci8) водитель. Вторая запись ссылается на предыдущую по внешнему ключу. Поэтому мне нужно иметь первичный ключ первой записи (он назначается из последовательности с триггером перед вставкой в ​​​​первой таблице), прежде чем я смогу вставить вторую запись.

Поэтому я экспериментировал, чтобы получить последний вставленный идентификатор:

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

Как получить последний вставленный идентификатор или как получить значение из сохраненной функции в Go от Oracle?


person Sergey Melekhin    schedule 15.12.2015    source источник
comment
либо вам нужно использовать orm, чтобы получить идентификатор последней вставленной строки (последний сохраненный объект), либо вы можете прекратить вставлять идентификатор через триггер. Вручную вы можете получить seq.nextVal и работать над ним   -  person Krishnat Molawade    schedule 15.12.2015
comment
Возможно, вы можете исправить драйвер go-oci8: github.com/mattn/go -oci8/blob/master/oci8.go?   -  person kostya    schedule 15.12.2015


Ответы (1)


Привет, я не знаю о go, но я знаю о запросе возврата оракула

Та же проблема, что и с PHP, и я решаю ее с помощью этого запроса

insert into table (field1,field2,field3)
values (val1,val2,val3) return primaryfield_id into :xx

Он автоматически вернет значение в вашей переменной Go (я думаю), попробуйте это

person Chintan Gor    schedule 28.12.2015
comment
Я тоже это пробовал. Переменная, привязанная к :xx, остается пустой после вызова. Похоже, что пакет базы данных/sql golang не может возвращать значения для связанных переменных. Только для того, чтобы передать их в запрос. - person Sergey Melekhin; 29.12.2015
comment
можете ли вы прислать мне результат вашего возвращаемого запроса v? - person Chintan Gor; 06.01.2016
comment
В go output, как я уже говорил ранее. Связанная переменная остается пустой. - person Sergey Melekhin; 11.01.2016