Uploaded image for project: 'CUBRID APIs'
  1. CUBRID APIs
  2. APIS-729

[ADO.NET] The CUBRIDCommand.GetGeneratedKeys() throws a "missing or invalid arguments" Exception

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: ADO.NET 9.3.0.0001
    • Fix Version/s: ADO.NET 9.3.0.0001
    • Component/s: ADO.NET
    • Labels:
    • Environment:

      Test Build: 9.3.0.0145
      Test OS: Windows 32bit
      .NET: 4.0
      Driver: cubrid-ado.net 9.3.0.0001(20140224)

      Description

      The CUBRIDCommand.GetGeneratedKeys() throws an undesired "missing or invalid arguments" Exception

      Scenario

      {code}
      CUBRIDConnection conn = new CUBRIDConnection()
      conn.ConnectionString = "server=localhost;database=demodb;port=33000;user=public;password=";
      conn.Open();
      conn.SetAutoCommit(false);

      CUBRIDTransaction transaction = conn.BeginTransaction();

      CUBRIDCommand cmd = new CUBRIDCommand("create table tkeys(id int auto_increment, str string)", conn)
      cmd.ExecuteNonQuery();

      cmd.CommandText = "insert into tkeys(str) values('xyz')";
      cmd.ExecuteNonQuery();

      DbDataReader reader = cmd.GetGeneratedKeys();{code}

      Output:

      CUBRID.Data.CUBRIDClient.CUBRIDException: Function called with missing or invalid arguments.
      

        Activity

        Show
        xiaoshan78 李成龙[이성룡] added a comment - Please refer to http://bts4.nhncorp.com/nhnbts/browse/CUBRIDSUS-13116
        Hide
        cn16359 唐勤 added a comment - - edited

        Root Cause
        The problem is caused by that a new execution option EXEC_FLAG_GET_GENERATED_KEYS = 0x40 is introduced in Cubrid 9.3.0. If this flag is not set when execute the sql statement, no key is generated. ADO.NET doesn't support this flag.
        Resolving Result
        Fixed. Add an isGeneratedKeys attribute to CUBRIDCommand. In order to get the generated keys,you must set isGeneratedKeys = true__ before execute the insert statement. See the example below:

        {code}
        cmd.IsGeneratedKeys = true; // set the isGeneratedKeys on before execute insert with auto increment.
        cmd.CommandText = "insert into tkeys(str) values('xyz')";
        cmd.ExecuteNonQuery();
        System.Data.Common.DbDataReader reader = cmd.GetGeneratedKeys();
        reader.Read();
        Console.WriteLine("key: " + reader.GetInt32(0));{code}

        Modification

        {code}
        public sealed class CUBRIDCommand : DbCommand, ICloneable
        {
        ...
        private bool isGeneratedKeys = false;
        public bool IsGeneratedKeys
        {
        get { return isGeneratedKeys; }
        set { isGeneratedKeys = value; }
        }
        ...
        internal CUBRIDDataReader ExecuteInternal()
        {
        ...
        CCIExecutionOption executionFlags = CCIExecutionOption.CCI_EXEC_QUERY_ALL;
        if (statementType == CUBRIDStatementType.CUBRID_STMT_INSERT && isGeneratedKeys == true)
        { executionFlags = executionFlags | CCIExecutionOption.CCI_EXEC_GET_GENERATED_KEYS; }
        int totalTupleCount = conn.Stream.RequestExecute(handle, executionFlags, parameters,
        paramModes, fetchFlag, conn.AutoCommit);
        ...
        }
        ...
        }{code}
        Show
        cn16359 唐勤 added a comment - - edited Root Cause The problem is caused by that a new execution option EXEC_FLAG_GET_GENERATED_KEYS = 0x40 is introduced in Cubrid 9.3.0. If this flag is not set when execute the sql statement, no key is generated. ADO.NET doesn't support this flag. Resolving Result Fixed. Add an isGeneratedKeys attribute to CUBRIDCommand. In order to get the generated keys,you must set isGeneratedKeys = true__ before execute the insert statement. See the example below: {code} cmd.IsGeneratedKeys = true; // set the isGeneratedKeys on before execute insert with auto increment. cmd.CommandText = "insert into tkeys(str) values('xyz')"; cmd.ExecuteNonQuery(); System.Data.Common.DbDataReader reader = cmd.GetGeneratedKeys(); reader.Read(); Console.WriteLine("key: " + reader.GetInt32(0));{code} Modification {code} public sealed class CUBRIDCommand : DbCommand, ICloneable { ... private bool isGeneratedKeys = false; public bool IsGeneratedKeys { get { return isGeneratedKeys; } set { isGeneratedKeys = value; } } ... internal CUBRIDDataReader ExecuteInternal() { ... CCIExecutionOption executionFlags = CCIExecutionOption.CCI_EXEC_QUERY_ALL; if (statementType == CUBRIDStatementType.CUBRID_STMT_INSERT && isGeneratedKeys == true) { executionFlags = executionFlags | CCIExecutionOption.CCI_EXEC_GET_GENERATED_KEYS; } int totalTupleCount = conn.Stream.RequestExecute(handle, executionFlags, parameters, paramModes, fetchFlag, conn.AutoCommit); ... } ... }{code}
        Hide
        cn16359 唐勤 added a comment -

        Fixed.

        Show
        cn16359 唐勤 added a comment - Fixed.
        Hide
        ryin005 Ray Yin added a comment -

        Add a case for this issue

        RB-9.3.0

        {code}
        CUBRIDConnection conn = new CUBRIDConnection();
        conn.ConnectionString = "server=locahost;database=demodb;port=33000;user=dba;password=";
        conn.Open();

        conn.SetAutoCommit(false);

        CUBRIDTransaction transaction = conn.BeginTransaction();

        CUBRIDCommand cmd = new CUBRIDCommand("drop table if exists tkeys", conn);
        cmd.ExecuteNonQuery();

        cmd = new CUBRIDCommand("create table tkeys(id int auto_increment(300,1), str string)", conn);
        cmd.ExecuteNonQuery();

        cmd.IsGeneratedKeys = true;
        cmd.CommandText = "insert into tkeys(str) values('xyz')";
        cmd.ExecuteNonQuery();

        DbDataReader reader = cmd.GetGeneratedKeys();

        while (reader.Read())
        {
        Console.WriteLine(reader.GetInt32(0));
        };

        cmd.Close();
        transaction.Commit();

        conn.Close();{code}

        Link: http://svn.bds.nhncorp.com/xdbms/cubridqa/branches/RB-9.3.0/interface/ADO.NET/unit_test/ADOTest/ADOTest/BTS_issue.cs

        Show
        ryin005 Ray Yin added a comment - Add a case for this issue RB-9.3.0 {code} CUBRIDConnection conn = new CUBRIDConnection(); conn.ConnectionString = "server=locahost;database=demodb;port=33000;user=dba;password="; conn.Open(); conn.SetAutoCommit(false); CUBRIDTransaction transaction = conn.BeginTransaction(); CUBRIDCommand cmd = new CUBRIDCommand("drop table if exists tkeys", conn); cmd.ExecuteNonQuery(); cmd = new CUBRIDCommand("create table tkeys(id int auto_increment(300,1), str string)", conn); cmd.ExecuteNonQuery(); cmd.IsGeneratedKeys = true; cmd.CommandText = "insert into tkeys(str) values('xyz')"; cmd.ExecuteNonQuery(); DbDataReader reader = cmd.GetGeneratedKeys(); while (reader.Read()) { Console.WriteLine(reader.GetInt32(0)); }; cmd.Close(); transaction.Commit(); conn.Close();{code} Link: http://svn.bds.nhncorp.com/xdbms/cubridqa/branches/RB-9.3.0/interface/ADO.NET/unit_test/ADOTest/ADOTest/BTS_issue.cs
        Hide
        ryin005 Ray Yin added a comment -

        Test Build: 9.3.0.0174
        Test OS: Windows 32bit
        .NET: 4.0
        Driver: cubrid-ado.net 9.3.0.0001(20140414)

        Test Result: Pass

        Close the issue

        Show
        ryin005 Ray Yin added a comment - Test Build: 9.3.0.0174 Test OS: Windows 32bit .NET: 4.0 Driver: cubrid-ado.net 9.3.0.0001(20140414) Test Result: Pass Close the issue

          People

          • Assignee:
            cn16359 唐勤
            Reporter:
            ryin005 Ray Yin
            CC (Referrer):
            Esen Sagynov, Isaiah Choe, 唐勤, 户向伟, 范再强, 谢韦华[Bert]
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: