2016-04-15 20 views
0

最後に挿入された行のIDを取得する必要があるC++コードを作成しています。 this link hereに基づいてOracle OCIは最後に挿入された行のIDを取得します

私はこのコードを作ったが、それは(無効な文字)だけゴミを返している:それを修正する方法について

std::string sql = "INSERT INTO MYTABLE (FIELD_A, FIELD_B) VALUES (10, 20)"; 

    OCIStmt *stmthp; 
    int sts = OCIHandleAlloc((dvoid *) envhp, (dvoid **) &stmthp, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0); 
    CheckOracleError(sts); 

    sts = OCIStmtPrepare(stmthp, errhp, (const OraText *) sql.c_str(), (ub4) sql.size(), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT); 
    CheckOracleError(sts); 

    sts = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_COMMIT_ON_SUCCESS); 

    if (sts != OCI_NO_DATA && sts != OCI_SUCCESS) 
     CheckOracleError(sts); 


    OraText rowID[19]; // Extra char for null termination. 
    ub2 size = 18; 
    OCIRowid *pRowID; 
    std::memset(rowID, 0, 19); // Set to all nulls so that string will be null terminated. 
    OCIDescriptorAlloc(envhp, (void**)&pRowID, OCI_DTYPE_ROWID, 0, NULL); 
    OCIAttrGet(stmthp, OCI_HTYPE_STMT, pRowID, 0, OCI_ATTR_ROWID, errhp); 
    OCIRowidToChar(pRowID, rowID, &size, errhp); 

    OCIHandleFree(stmthp, OCI_HTYPE_STMT); 

任意のアイデア?

+1

'ROWID'は[Oracleが生成する疑似列](https://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns008.htm)であり、** NOT **の主キーです。データが削除されて再入力された場合、または行の移動が有効になっている場合は、テーブルを変更することができます。好ましくはシーケンスによって生成されたテーブル用の主キー、または12cでID列が生成されている必要があります。 – MT0

+0

Hummm。私はそれを得ました....実際に**私は* ID *というプライマリキーを持っています**は、シーケンスによって生成されます。 'ROWID'ではなく、最後に挿入された行からこのIDを取得する必要があります....どうすればいいですか? – Mendes

答えて

2

あなたはテーブルがある場合:

CREATE TABLE mytable (
    ID  INT PRIMARY KEY, 
    FIELD_A INT, 
    FIELD_B INT 
); 

をあなたはシーケンスを作成することができます

CREATE SEQUENCE mytable__id__seq; 

次に、あなたが手続きを経てすべての挿入を行うことができます(とグループにすべてのパッケージを使用することができます機能を1つの場所に作成/読み込み/更新/削除する場合)、パッケージ内でRETURNING .. INTO ..を使用して、出力変数から値を取得することができます。

CREATE OR REPLACE PACKAGE mytable_pkg 
AS 
    PROCEDURE add(
    i_field_a IN MYTABLE.FIELD_A%TYPE, 
    i_field_b IN MYTABLE.FIELD_B%TYPE, 
    o_id  OUT MYTABLE.ID%TYPE 
); 

    -- PROCEDURE edit(...); 
    -- PROCEDURE del(...); 
END mytable_pkg; 
/


CREATE OR REPLACE PACKAGE BODY mytable_pkg 
AS 
    PROCEDURE add(
    i_field_a IN MYTABLE.FIELD_A%TYPE, 
    i_field_b IN MYTABLE.FIELD_B%TYPE, 
    o_id  OUT MYTABLE.ID%TYPE 
) 
    AS 
    BEGIN 
    INSERT INTO mytable (
     id, 
     field_a, 
     field_b 
    ) VALUES (
     mytable__id__seq.NEXTVAL, 
     i_field_a, 
     i_field_b 
    ) 
    RETURNING id INTO o_id; 
    END add; 

    -- PROCEDURE edit(...); 
    -- PROCEDURE del(...); 
END mytable_pkg; 
/

次に、OCIを使用してストアド・プロシージャをコールし、outパラメータのバインドされた値を使用できます。参照できる例(例:herehere)が多数あります。

+0

いつこのIDを使用する予定ですか? PK(または他のもの)に使用される値は、(1)COMMITされるまで他のセッションには見えないこと、(2)挿入トランザクションがロールバックされると永遠に失われることに注意してください。 – EdStevens

関連する問題