HOW TO GET AUTO GENERATED PRIMARY ID KEY BACK FROM AN INSERT STATEMENT IN .

Just recently I ran into a problem with what seems to be a deficiency in the Oracle Database. When trying to return an auto-generated key as is done in Microsoft's SQL database, it seems Oracle for whatever reason didn't add this capability, the key couldn't be passed back to the .Net call. After tinkering with the .Net software and talking with the Oracle techs, a decent work around to the problem (presented here) comes fairly close. Two things have to be done first before this will work. A sequence has to be created on the Oracle DB. Also a trigger has to be created against the table the keys are going to be returned from.
The class works by passing to the function 'update_datasets_return' a DataSet with as many tables as you want. The function spins through the tables and put the keys in each row inserted. It's assumed the first row will either be the primary key or some numeric value. This can be changed by modifying the: dt.Columns(0).ColumnName
Notice the word Inserted. On Updates and Deletes the key value is ignored because it's already present. The routine just updates the database as usual.
So in other words you could send a table to the function with rows inserted, deleted, or updated and it will take care of them all. One routine for all.
' ======================================================================
' Created by SEF and Oracle SR: 5607364.993 This is a complete Redo
' of the initial concept. SEF...
' Sample of sequence and trigger at bottom.
' Uses the ODP.NET data provider.
' update_datasets_return: Goes thru each table in the dataset and
' updates, deletes, or inserts as needed.
' If inserting, a 'sequence counter' and a 'trigger'
' using the 'before insert' must be present. The sequence
' counter is set to auto increment by 1 starting at 1.
' The trigger is specific to the table.
' Create the trigger and sequence in the database or run the samples
' below in PL/SQL. Be sure the logon with a user that has enough rights.
' Routine assumes the first column is going to hold the sequence
' number. Actually any column could be used. Just change the
' dt.Columns(0).ColumnName to whatever you want or leave as default.
' The da_RowUpdated sub is where the 'sequence number' gets returned
' on each row that is inserted into a table. Routine is ignored on
' deletes and updates. SEF...
' =======================================================================
Imports System
Imports System.Data
Imports Oracle.DataAccess.Client
Imports Oracle.DataAccess.Types
Public Class OracleUpdate
Private Shared m_conn As OracleConnection
Private Shared da As New OracleDataAdapter
Private Shared dt As DataTable
Private Shared conn As New OracleConnection
Private Shared dr As DataRow
Private Shared astep As Long
Private Shared rwIndex As Integer = 0
Private Shared tblIndex As Integer = 0
Public Shared Function update_datasets_return(ByVal constr As String, ByVal ds As DataSet) As DataSet ''ByRef ds As DataSet)
Dim selectstmt As String
m_conn = New OracleConnection(constr)
Try
m_conn.Open()
Catch ex As Exception
Throw New ArgumentException(" Error: connection lost." & ex.Message)
End Try
For Each dt In ds.Tables
''Uncomment the code only if auto numbering
''is NOT turned on for the table being updated. SEF...
''rwIndex = 0
''For Each dr In dt.Rows
'' Try
'' Select Case dr.RowState
'' Case DataRowState.Added
'' astep += 1
'' ' =======================================================
'' ' This "Try Catch" section created only if auto numbering
'' ' is NOT turned on for the table being updated. SEF...
'' ' It's a crude attempt at creating a unique number.
'' ' A more serious approach would be to use a GUID.
'' ' Use only if you decide not to have a sequence and a
'' ' trigger for the table.
'' ' =======================================================
'' Try
'' 'ds.Tables(tblIndex).Rows(rwIndex).Item(0) = astep
'' Catch
'' ' ignore the error corrected integer identity so don't randomize it
'' End Try
'' dr.Item("createdDate") = Now
'' dr.Item("changedDate") = Now
'' Case DataRowState.Modified
'' dr.Item("changedDate") = Now
'' End Select
'' Catch ex As Exception
'' conn.Close()
'' conn.Dispose()
'' Throw New ArgumentException(" Error: update_datasets " & ex.Message)
'' End Try
'' rwIndex += 1
''Next
selectstmt = "SELECT * From " & dt.TableName & " Where " & dt.Columns(0).ColumnName & " = " & 0
da = New OracleDataAdapter(selectstmt, m_conn)
Dim bldr As OracleCommandBuilder = New OracleCommandBuilder(da)
AddHandler da.RowUpdated, New Oracle.DataAccess.Client.OracleRowUpdatedEventHandler(AddressOf da_RowUpdated)
Dim insCmd As OracleCommand = Nothing
Try
insCmd = CType(bldr.GetInsertCommand(), OracleCommand)
Catch ex As Exception
Throw New Exception("")
End Try
insCmd.CommandText += " returning " + dt.Columns(0).ColumnName + " into :seqno"
insCmd.Parameters.Add(New OracleParameter("seqno", OracleDbType.Int16, _
4, ParameterDirection.Output, False, CType(0, System.Byte), CType(0, _
System.Byte), dt.Columns(0).ColumnName, DataRowVersion.Current, Nothing))
da.InsertCommand = insCmd
Try
' ===========================
da.Update(ds, dt.TableName)
' ===========================
Catch ex As Exception
Throw New ArgumentException(" Error: update_datasets_return " & ex.Message)
End Try
Next
m_conn.Close()
m_conn.Dispose()
Return ds
End Function
Friend Shared Sub da_RowUpdated(ByVal sender As Object, ByVal e As OracleRowUpdatedEventArgs)
If e.StatementType = StatementType.Insert Then
e.Row(0) = Int64.Parse(e.Command.Parameters("seqno").Value.ToString())
End If
End Sub
' ================================================================================
' Notes:
' =================== How To -- Sample section for PL/SQL ==================================
' myTrigger, myTable, mySequence, and myColumn are values you need to supply.
' Note: A trigger needs to be created for each table.
' A sequence needs to be created only once and referenced each time
' in the trigger(s). Or you could create a new sequence each time you
' create a trigger. Sort of a waste of effort.
' Explanation:
' myTrigger = The name you are giving this trigger.
' If a trigger with same name already
' exist, it will be overwritten.
' myTable = Table you want to add the sequence numbers to.
' mySequence = Sequence counter you created. Whatever name you called it.
' myColumn = The column to update with the sequence number.
' =================================================================================
' -- Run in PL/SQL or create at DB. --
' create or replace trigger myTrigger
' before insert on myTable for each row
' begin
' select mySequence.nextval into :new.myColumn from dual ;
' end;
' -- Run in PL/SQL or create at DB. --
' create sequence mySequence
' MINVALUE 1
' START WITH 1
' INCREMENT BY 1
' NOCACHE; can be set to CACHE but sequence may contain gaps.
' Explanation of CACHE from: http://www.techonthenet.com/oracle/sequences.php
' With respect to a sequence, the CACHE option specifies how many sequence
' values will be stored in memory for faster access. The downside of creating
' a sequence with a CACHE is that if a system failure occurs, all cached
' sequence values that have not be used, will be "lost". This results in
' a "gap" in the assigned sequence values. When the system comes back up,
' Oracle will CACHE new numbers from where it left off in the sequence,
' ignoring the so called "lost" sequence values.
' Note: To recover the lost sequence values, you can always execute an
' ALTER SEQUENCE command to reset the counter to the correct value.
' NOCACHE means that none of the sequence values are stored in memory.
' This option may sacrifice some performance, however, you should not encounter
' a gap in the assigned sequence values.
End Class
C#:
using System;
using System.Data;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
public class OracleUpdater2
private static OracleConnection m_conn;
private static OracleDataAdapter da = new OracleDataAdapter();
private static OracleConnection conn = new OracleConnection();
public static DataTable load_it(string constr, string strqry, string tblName)
// =====================================================================
// constr = User Id=myUser;Password=myPass";Data Source=myDataSource
// strqry = Select * from something?
// tblName = The table name to fill.
// =====================================================================
conn = new OracleConnection(constr);
conn.Open();
da = new OracleDataAdapter(strqry, conn);
OracleCommandBuilder bldr = new OracleCommandBuilder(da);
DataTable dt = new DataTable(tblName);
da.Fill(dt);
conn.Dispose();
return dt;
public static DataSet update_datasets_return(string constr, DataSet ds)
//'ByRef ds As DataSet)
string selectstmt = null;
m_conn = new OracleConnection(constr);
try
m_conn.Open();
catch (Exception ex)
throw new ArgumentException(" Error: connection lost." + ex.Message);
foreach (DataTable dt in ds.Tables)
selectstmt = "SELECT * From " + dt.TableName + " Where " +
dt.Columns[0].ColumnName + " = " + 0;
da = new OracleDataAdapter(selectstmt, m_conn);
OracleCommandBuilder bldr = new OracleCommandBuilder(da);
da.RowUpdated += new
Oracle.DataAccess.Client.OracleRowUpdatedEventHandler(da_RowUpdated);
OracleCommand insCmd = null;
try
insCmd = (OracleCommand)(bldr.GetInsertCommand());
catch (Exception ex)
throw new Exception("" + ex.Message);
insCmd.CommandText += " returning " + dt.Columns[0].ColumnName + " into
:seqno";
insCmd.Parameters.Add(new OracleParameter("seqno", OracleDbType.Int16, 4,
ParameterDirection.Output, false, System.Convert.ToByte(0),
System.Convert.ToByte(0), dt.Columns[0].ColumnName, DataRowVersion.Current,
null));
da.InsertCommand = insCmd;
try
// ===========================
da.Update(ds, dt.TableName);
// ===========================
catch (Exception ex)
throw new ArgumentException(" Error: update_datasets_return " +
ex.Message);
m_conn.Close();
m_conn.Dispose();
return ds;
If you need a working program of how this works, let me know.

Oh my god, it is too long! You definitely check out types, casting and especially ODP.Net (it does everything for you)... etc. They can help you to simplify your code. I do not have enough time to copy paste it to Studio and understand and solve your issue, so I got title of your message as your main question.
In Oracle, you can create an autonumber field by using sequences object. This is really useful when you need to create a unique number to act as a primary key.
Basically you can create a sequence simply typing;
CREATE SEQUENCE MY_SEQUENCE;
now you have a sequence called "MY_SEQUENCE"... Then, I advice you select a number from sequence;
select MY_SEQUENCE.nextval from dual;
I said I advice actually kinda must, although it called sequence, I cannot be sequential. Do not even try to predict the value. You can be sure that it is unique number so you can use it.
Then insert you record and use that number part of your primary key. I think that's it. Have fun.

Similar Messages

  • How to get auto generated column in spring jdbc

    Hi guys ,
    I am using springJDBC and sybase db.
    I think what i am facing is a standard problem but whatever support i am getting from google is not working.
    My problem is :
    "While inserting values in database one colum is autogenerated .....how do i get the value of that column??"
    FYI,
    I have tried using the following code :
    "final String INSERT_SQL = "insert into my_test (name) values(?)";
    final String name = "Rob";
    KeyHolder keyHolder = new GeneratedKeyHolder();
    jdbcTemplate.update(
    new PreparedStatementCreator() {
    public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
    PreparedStatement ps =
    connection.prepareStatement(INSERT_SQL, new String[] {"id"});
    ps.setString(1, name);
    return ps;
    keyHolder);
    // keyHolder.getKey() now contains the generated key"
    but i am getting this error : "java.lang.AbstractMethodError: com.sybase.jdbc2.jdbc.SybConnection.prepareStatement(Ljava/lang/String;I)Ljava/sql/PreparedStatement"
    I think this code works well with Oracle but not with sybase .........does anyone know the solution of this problem .......and by "this problem" i mean how to retrieve auto generate value in spring jdbc ...........without using SimpleJdbcInsert class

    Looking at the previous post it doesn't look like a Spring issue.
    You are using a JDBC driver which does not support getting generated keys so you have 2 choices:
    - Use a different driver that supports generated keys
    - Get the generated key by issuing some vendor specific SQL e.g. 'select @@identity' for SQL server

  • How to get auto generated key when inserting  using C#

    I inserted a row in a table in oracle 11g as follows:
    public void add(Admin admin)
    OracleConnection myOracleConnection =
    new OracleConnection(connStr);
    myOracleConnection.Open();
    OracleCommand myOracleCommand = myOracleConnection.CreateCommand();
    myOracleCommand.CommandText = "Insert into Admin values(adminSeq.nextVal,:name) returning admin_id into :adminId";
    myOracleCommand.Parameters.Clear();
    OracleParameter para=new OracleParameter(":adminId",ParameterDirection.Output);
    myOracleCommand.Parameters.Add(para);
    myOracleCommand.Parameters.Add(":name", admin.Name);
    myOracleCommand.ExecuteNonQuery();
    admin.AdminId = int.Parse(myOracleCommand.Parameters[":adminId"].Value.ToString());
    I found a new row a ADMIN, but I can not get the PK when inserting. the value of "myOracleCommand.Parameters[":adminId"].Value" is always "OUTPUT" , any ideas?
    Thank you.
    Edited by: user11228816 on 2010-3-1 上午12:17

    Does not seem to be an Oracle issue itself. Your approach is correct. E.g.
    SQL> create table foo( id number, name varchar2(20) );
    Table created.
    SQL>
    SQL> create sequence foo_id start with 1 increment by 1 nomaxvalue nocycle;
    Sequence created.
    SQL>
    SQL> var id number
    SQL> insert into foo values( foo_id.nextval, 'test1') returning id into :id;
    1 row created.
    SQL>
    SQL> print id
            ID
             1
    SQL>Check your bind calls. Is the bind name index value for example not perhaps +["adminId"]+ (no bind char marker)?
    Also, the binding of the output parameter, i.e.
    para=new OracleParameter(":adminId",ParameterDirection.Output);In OCI, when binding, one needs to specify the data type for the bind. When binding strings for example, the length also needs to be specified. This bind seems to be untyped. Yet, you apply a "+ToString()+" method to it when referencing it.. how would the Parameters class know its data type?
    Can you do explicit data type binding in C#? If so, try and bind the parameter explicitly as an integer and reference it as an integer when getting its value.

  • The user acct my apple was connected to no longer works (corrupt).  My Apple TV is still synced to that account and all of my recent purchases are going to that username.  Does anyone know how to get all of the purchased items back and to the new user?

    The user profile my appleTV was synced on my computer to no longer works (corrupt).  My Apple TV is still synced to that profile and all of my recent purchases are going to that username.  Does anyone know how to get all of the purchased items back and to the new user (same computer)?  I created a new user on my computer and moved the itunes folder to the desktop but never changed the path to which the apple synced to.  Now I can only see old items I purchased before the user profile went bad.  PLease help!

    Welcome to the Apple Community.
    Changing the library the Apple TV is synced with will delete all synced content from the Apple TV, but it won't delete purchased content.
    You should be able to change the library, resync any content you want and transfer your purchases back to the new library.

  • Okay i had to install Itunes onto my new OS because window's Vista messed up on me and i can't get any of my old purchases back from my account such as music and movies any ideas on how to get them back (i do not have the folder that contains old items)

    Okay i had to install Itunes onto my new OS because window's Vista messed up on me and i can't get any of my old purchases back from my account such as music and movies any ideas on how to get them back (i do not have the folder that contains old items from the last itunes or anything from that OS because it had a virus and i just wanted windows 7)

    Downloading past purchases from the App Store, iBookstore, and iTunes Store
    Hope this helps,
    JD

  • How to get the current JSF phase in backing bean?

    How to get the current JSF phase in backing bean?
    Edited by: jimmy6 on Nov 27, 2007 7:27 AM

    I am using phasetracker to trace it also.I want to know whether it is it render response phase. I know FacesContext.getCurrentInstance().getRenderResponse() work for normal jsf component but it will not work for qiupukit datatable. FacesContext.getCurrentInstance().getRenderResponse() will not return true in the following phase. Why?
    [ INFO] 27-11-07 16:20:21 : BEFORE RENDER_RESPONSE(6) (http-80-Processor23)
    I want the 'get' method of datatable being called in response phase to reduce the number of calling because i put the query in 'get' method there. Actually i still straggling with the best practice to code the datatable...

  • How to get the form reference in .js page from .jsp page

    hi
    i have written one form in jsp page omething like:-
    <html:form action="/shopping" onsubmit="return false;">
    can anybody tell me,how to get the form reference in .js page from .jsp page ,
    i have tried:-
    var formRef = document.forms[0];
    butits not working.
    Thanks.

    Its very simple......y cant u prefer google...Bad
    c this example...
    function submit()
    alert("textbox"+ document.forms[0].name.value);//to get textbox value in js
    document.forms[0].submit();//to submit jsp page using js
    <html:html>
    <html:form action="/shopping" onsubmit="submit()">
    <html:text property=name>
    learn to search in google..
    </html:form>
    </html:html>

  • How to get the first day in the month from a domain date ?

    Hi,
    I like to know how to get the first day in the month from a domain date?
    Thanks
    Stephen

    Hi Gokul...
    Instead of using the funtion module you can just write the 3 statements of code to get the first day of the week.
    Its similar to the above one but instead of writing case statement you can achive the following.
    data : w_res type i,
             w_data type d,
    w_res = w_date mod 7.
    w_date = w_date - w_res.
    write w_date.
    This works.
    Regards,
    Siddarth

  • How to get the absolute path of a file from the local disk given the file n

    how to get the absolute path of a file from the local disk given the file name

    // will look for the file at the current working directory
    // this is wherever you start the Java application (cound be C: and your
    // application is located in C:/myapp, but the working dir is C:/
    File file = new File("README.txt"); 
    if (file != null && file.exists())
        String absolutePath = file.getAbsolutePath();

  • How to get safecontrol tag section to a collection from web.config in c#

    how to  get safecontrol tag section to a collection from web.config in c#
    Below is my config file. I need to read the safecontrol tagsection and get all those in to a collection.please help me on this.
    <?xml
    version="1.0"
    encoding="UTF-8"
    standalone="yes"?>
    <configuration>
    <SafeControls>
    <SafeControl
    Assembly="System.Web,
    Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
    Namespace="System.Web.UI.WebControls"
    TypeName="*"
    Safe="True"
    AllowRemoteDesigner="True"
    SafeAgainstScript="False"
    />
    <SafeControl
    Assembly="System.Web,
    Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
    Namespace="System.Web.UI.HtmlControls"
    TypeName="*"
    Safe="True"
    AllowRemoteDesigner="True"
    SafeAgainstScript="False"
    />
    </
    SafeControls>
    </configuration>
    adityadugyala

    Here is the way to read and write custom sections programtically in web.config.
    http://msdn.microsoft.com/en-us/library/2tw134k3.aspx
    Or use the traditional way of reading XML with XMLDocument.
    Bala

  • How  we get the component at front or back in a Jpanel

    How we get the component at front or back in a Jpanel. I want to manage the Z-axis position of the components in the Jpanel.

    [url http://java.sun.com/docs/books/tutorial/uiswing/components/layeredpane.html]How to Use Layered Panes

  • I have been charged 274.55 from 8-23-2013 - 8-26-2013. These are not my charges. I need to know how to get the charges reversed and put back on my account ASAP. Please confirm!

    I have been charged 274.55 from 8-23-2013 - 8-26-2013. These are not my charges. I need to know how to get the charges reversed and put back on my account ASAP. Please confirm!

    You can contact iTunes Support via this page (we are fellow users here on these forums) : http://www.apple.com/support/itunes/contact/ - click on Contact iTunes Store Support on the right-hand side of the page, then Purchases, Billing & Redemption

  • How to get string (specified by line and column) from txt file with labview

    Hi everyone
    How to get string (specified by line and column) from txt file with labview
    thx 
    Solved!
    Go to Solution.

    As far as I know, a text file has no columns.  Please be more specific.  Do you mean something like the 5th word on line 4, where words are separated by a space, and lines are separated by a newline character?  You could the Read from Spreadsheet String function and set the delimiter to a space.  This will produce a 2D array of strings.  Then use index array and give the line number and column number.
    - tbob
    Inventor of the WORM Global

  • How to get G/L account and cost centres from ECC to SRM...

    Dear All,
    How to get G/L account and cost centres from ECC to SRM...
    Please let me know the steps...
    Thanks
    Ravi

    Hi
    GL account - You can define in SPRO- Cross application settings--Account assignment ->Define GL account for product category and account assignment category.
    or you can use BADI BBP_DETERMINE_ACCT.
    In Organisation Strucute - You can Map the backend cost center via KNT  cost center attribute .
    Regards
    Muthu

  • How to "auto" generate "Primary Key" in custom table?

    Hi Folks,
    Requirement:
    I need a function module or program that can create automatically a primary key.
    Scenario:
    I have a program that creates an entries and save it to a custom table at the same time, but a primary key should always be generated respective to the entries saved.
    Example:
    Material(MATNR) 4001001, Plant(WERKS) XX01, ID[Primary Key-auto generated]
    (I'm thinking of a similar concept/logic on how a unique IDOC number is being generated or how SAP standard creates a unique entry)
    I try to look for any SAP FM that can generate a PK, but there's no luck.
    Thanks.
    Regards,
    Jun

    Hi Keshu and All,
    The links are helpful, however:
    #1. I don't have authorization to create a new object in transaction SNRO, but the way I see the objects in SNRO is just for defining the length(number of characters) for the ranges that will be use if I'm not mistaken.
    #2. FM NUMBER_GET_NEXT - yes it can populate incremental unique entries but it's only occurring at runtime ?? So when the program get terminated it's not being saved nowhere.
    So after if I use FM NUMBER_GET_NEXT, I always have to look for all the last primary key in my custom table, then target it as my starting point for creating a new PK.  I think this will give a performance issue, any comments?
    For better visualization, I have scenario:
    1.  (ZQ_CREATE_PK) Create unique incremental PK for material, batch, so on..
    2.  Append line/entries to ZQ_TABLE
    3.  Repeat #1 and #2
    4.  User exits the program
    5.  Back to 1 --> At this point, I need to get the "LATEST" PK then start this as a starting point again to generate PK and append it to ZQ_TABLE
    I'm assuming that SAP has other SAP FMs related in creating this scenario.   Similar to IDOC # creation..
    Thanks.

Maybe you are looking for

  • ISR router cannot receive packets addressed to itself?

    Hello, Support Team and All Members, I have a C881G router connected to 2 different ISP networks with a failover function configured and running properly. The following is a simple network diagram: The main WAN traffic goes through the ISP 1 LTE netw

  • IPad captured video and Final Cut Pro

    hello, i am editing videos captured with an iPad 2 in FInal Cut Pro 7, but Final Cut is running really slow and rendering becomes impossible when adding a second video track with either video or photoshop files with a transparency for example. There

  • HT4623 Looks like a Bug in the Default Mail application of iOS 6 in an iPhone 4S

    In the mail application of my iPhone 4S running iOS6, while composing a new email, the recipients field marked as "To: " doesn't respond in a single tap rather requires two or three and sometimes even more taps for the blue input bar to appear and en

  • Any way to store websites outside of iweb?

    I have built a few websites in iweb including one that has pics of my daughter's field hockey games for the entire fall season. Even with the photo sizes reduced, the volume of pics (over 3000, yes, we went a little nuts) is huge and is really slowin

  • Is a Servlet-Filter which serializes requests in the same user session ok?

    The Servelt specification states that the Web-Application is itself responsible for synchronizing access to HttpSessions. It is from the serversite not possible to prevent multiple threads to access the same HttpSession (i.e. the user could always op