예제 #1
0
        private DB2Environment()
        {
            connectionPools = Hashtable.Synchronized(new Hashtable());

            //			short sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_ENV, IntPtr.Zero, ref penvHandle);
            short sqlRet = DB2CLIWrapper.Initialize(ref penvHandle);

            DB2ClientUtils.DB2CheckReturn(sqlRet, 0, IntPtr.Zero, "Unable to allocate Environment handle.", null);

            // SQLSetEnvAttr( hEnv=0:1, fAttribute=SQL_ATTR_APP_TYPE 2473, vParam=4, cbParam=0 )	// 4=ADO.NET apptype????
            // SQLSetEnvAttr( hEnv=0:1, fAttribute=SQL_ATTR_OUTPUT_NTS 10001, vParam=0, cbParam=0 ) // strings not 0-terminated
        }
예제 #2
0
        private void FreeHandles()
        {
            if (dbHandle != IntPtr.Zero)
            {
                short sqlRet = DB2CLIWrapper.SQLDisconnect(dbHandle);
                // Note that SQLDisconnect() automatically drops any statements and
                // descriptors open on the connection.
                sqlRet = DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_DBC, dbHandle);

                dbHandle = IntPtr.Zero;
            }
        }
예제 #3
0
        public DB2OpenConnection GetOpenConnection(DB2Connection db2Conn)
        {
            DB2OpenConnection connection = null;

            lock (openFreeConnections.SyncRoot)
            {
                if ((connectionSettings.ConnectionPoolSizeMax > 0) && (connectionsOpen >= connectionSettings.ConnectionPoolSizeMax))
                {
                    throw new ArgumentException("Maximum connections reached for connectionstring");
                }

                while (connectionsOpen > connectionsInUse)
                {
                    connection = (DB2OpenConnection)openFreeConnections[openFreeConnections.Count - 1];
                    openFreeConnections.RemoveAt(openFreeConnections.Count - 1);

                    // check if connection is dead
                    int isDead;
                    DB2Constants.RetCode sqlRet = (DB2Constants.RetCode)DB2CLIWrapper.SQLGetConnectAttr(connection.DBHandle, DB2Constants.SQL_ATTR_CONNECTION_DEAD, out isDead, 0, IntPtr.Zero);
                    if (((sqlRet == DB2Constants.RetCode.SQL_SUCCESS_WITH_INFO) || (sqlRet == DB2Constants.RetCode.SQL_SUCCESS)) && (isDead == DB2Constants.SQL_CD_FALSE))
                    {
                        connectionsInUse++;
                        break;
                    }
                    else
                    {
                        connectionsOpen--;
                        connection.Dispose();
                        connection = null;
                    }
                }
                if (connectionsOpen == connectionsInUse)
                {
                    if (timer != null)
                    {
                        timer.Dispose();
                        timer = null;
                    }
                }
            }
            if (connection == null)
            {
                openFreeConnections.Clear();
                connectionsUsableOffset = 0;

                connection = new DB2OpenConnection(connectionSettings, db2Conn);
                connectionsOpen++;
                connectionsInUse++;
            }

            return(connection);
        }
예제 #4
0
        private void InternalOpen(string connnectionString, DB2Connection connection)
        {
            try
            {
                DB2Constants.RetCode sqlRet = (DB2Constants.RetCode)DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_DBC, DB2Environment.Instance.PenvHandle, out dbHandle);
                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, DB2Environment.Instance.PenvHandle, "Unable to allocate database handle in DB2Connection.", connection);

                StringBuilder outConnectStr = new StringBuilder(DB2Constants.SQL_MAX_OPTION_STRING_LENGTH);
                short         numOutCharsReturned;

                sqlRet = (DB2Constants.RetCode)DB2CLIWrapper.SQLDriverConnect(dbHandle, IntPtr.Zero,
                                                                              connnectionString, DB2Constants.SQL_NTS,
                                                                              outConnectStr, DB2Constants.SQL_MAX_OPTION_STRING_LENGTH, out numOutCharsReturned,
                                                                              DB2Constants.SQL_DRIVER_NOPROMPT);

                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, dbHandle, "Unable to connect to the database.", connection);

                databaseProductName = SQLGetInfo(dbHandle, DB2Constants.SQL_DBMS_NAME);
                databaseVersion     = SQLGetInfo(dbHandle, DB2Constants.SQL_DBMS_VER);

                /* Set the attribute SQL_ATTR_XML_DECLARATION to skip the XML declaration from XML Data */
                sqlRet = (DB2Constants.RetCode)DB2CLIWrapper.SQLSetConnectAttr(dbHandle, DB2Constants.SQL_ATTR_XML_DECLARATION, new IntPtr(DB2Constants.SQL_XML_DECLARATION_NONE), DB2Constants.SQL_NTS);
                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, dbHandle, "Unable to set SQL_ATTR_XML_DECLARATION", connection);


                connection.NativeOpenPerformed = true;

                if ((settings.Pool == null) || (settings.Pool.databaseProductName == null))
                {
                    settings.Pool.databaseProductName = databaseProductName;
                    settings.Pool.databaseVersion     = databaseVersion;
                }
                else if (settings.Pool != null)
                {
                    if (settings.Pool != null)
                    {
                        databaseProductName = settings.Pool.databaseProductName;
                        databaseVersion     = settings.Pool.databaseVersion;
                    }
                }
            }
            catch
            {
                if (dbHandle != IntPtr.Zero)
                {
                    DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_DBC, dbHandle);
                    dbHandle = IntPtr.Zero;
                }
                throw;
            }
        }
예제 #5
0
        public string SQLGetInfo(IntPtr dbHandle, short infoType)
        {
            StringBuilder sb = new StringBuilder(DB2Constants.SQL_MAX_OPTION_STRING_LENGTH);
            short         stringLength;

            DB2Constants.RetCode sqlRet = (DB2Constants.RetCode)DB2CLIWrapper.SQLGetInfo(dbHandle, infoType, sb, DB2Constants.SQL_MAX_OPTION_STRING_LENGTH, out stringLength);

            if (sqlRet != DB2Constants.RetCode.SQL_SUCCESS && sqlRet != DB2Constants.RetCode.SQL_SUCCESS_WITH_INFO)
            {
                throw new DB2Exception(DB2Constants.SQL_HANDLE_DBC, dbHandle, "SQLGetInfo Error");
            }

            return(sb.ToString().Trim());
        }
예제 #6
0
        internal void AllocateStatement(string location)
        {
            if (db2Conn.DBHandle.ToInt32() == 0)
            {
                return;
            }
            DB2Constants.RetCode sqlRet;
            sqlRet = (DB2Constants.RetCode)DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_STMT, db2Conn.DBHandle, out hwndStmt);
            if ((sqlRet != DB2Constants.RetCode.SQL_SUCCESS) && (sqlRet != DB2Constants.RetCode.SQL_SUCCESS_WITH_INFO))
            {
                throw new DB2Exception(DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, location + ": Unable to allocate statement handle.");
            }

            parameters.HwndStmt = hwndStmt;

            SetStatementTimeout();
        }
예제 #7
0
        private void CloseStatementHandle(bool dispose)
        {
            if (hwndStmt != IntPtr.Zero)
            {
                if (statementOpen)
                {
                    short sqlRet = DB2CLIWrapper.SQLFreeStmt(hwndStmt, DB2Constants.SQL_CLOSE);
                }
                if ((!prepared && statementOpen) ||
                    dispose)
                {
                    short sqlRet = DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_STMT, hwndStmt);

                    hwndStmt = IntPtr.Zero;
                    prepared = false;
                }
                statementOpen = false;
            }
        }
예제 #8
0
        public DB2ErrorCollection(short sqlHandleType, IntPtr sqlHandle)
        {
            StringBuilder sqlState     = new StringBuilder(10);
            StringBuilder errorMessage = new StringBuilder(1025);

            int   sqlReturn;
            short recNum = 1;

            do
            {
                int   nativeError;
                short errorMessageLength;
                sqlReturn = DB2CLIWrapper.SQLGetDiagRec(sqlHandleType, sqlHandle, recNum++, sqlState, out nativeError, errorMessage, errorMessage.Capacity - 1, out errorMessageLength);
                if (sqlReturn == 0)
                {
                    Add(new DB2Error(errorMessage.ToString(), sqlState.ToString(), nativeError));
                }
            }while (sqlReturn == 0);
        }
예제 #9
0
        internal DB2Transaction(DB2Connection con, IsolationLevel isoL)
        {
            long db2IsoL;

            connection = con;
            short sqlRet;

            isolationLevel = isoL;

            switch (isoL)
            {
            default:
            case System.Data.IsolationLevel.Chaos:                                      //No DB2equivalent, default to SQL_TXN_READ_COMMITTED
            case System.Data.IsolationLevel.ReadCommitted:                              //SQL_TXN_READ_COMMITTED
                db2IsoL = DB2Constants.SQL_TXN_READ_COMMITTED;
                break;

            case System.Data.IsolationLevel.ReadUncommitted:                            //SQL_TXN_READ_UNCOMMITTED
                db2IsoL = DB2Constants.SQL_TXN_READ_UNCOMMITTED;
                break;

            case System.Data.IsolationLevel.RepeatableRead:                             //SQL_TXN_REPEATABLE_READ
                db2IsoL = DB2Constants.SQL_TXN_REPEATABLE_READ;
                break;

            case System.Data.IsolationLevel.Serializable:                               //SQL_TXN_SERIALIZABLE_READ
                db2IsoL = DB2Constants.SQL_TXN_SERIALIZABLE_READ;
                break;
            }

            //AutoCommit
            if (connection.AutoCommit)
            {
                sqlRet = DB2CLIWrapper.SQLSetConnectAttr(connection.DBHandle, DB2Constants.SQL_ATTR_AUTOCOMMIT, new IntPtr(DB2Constants.SQL_AUTOCOMMIT_OFF), 0);
                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, connection.DBHandle, "Error setting AUTOCOMMIT OFF in transaction CTOR.", connection);
                connection.AutoCommit = false;
            }
            sqlRet = DB2CLIWrapper.SQLSetConnectAttr(connection.DBHandle, DB2Constants.SQL_ATTR_TXN_ISOLATION, new IntPtr(db2IsoL), 0);
            DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, connection.DBHandle, "Error setting isolation level.", connection);

            state = TransactionState.Open;
        }
예제 #10
0
        public int ExecuteNonQuery()
        {
            ExecuteNonQueryInternal(CommandBehavior.Default);

            int numRows;

            //How many rows affected.  numRows will be -1 if we aren't dealing with an Insert, Delete or Update, or if the statement did not execute successfully
            short sqlRet = DB2CLIWrapper.SQLRowCount(hwndStmt, out numRows);

            DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecDirect error.", db2Conn);

            do
            {
                sqlRet = DB2CLIWrapper.SQLMoreResults(this.hwndStmt);
                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "DB2ClientDataReader - SQLMoreResults", db2Conn);
            }while(sqlRet != DB2Constants.SQL_NO_DATA_FOUND);

            CloseStatementHandle(false);

            return(numRows);
        }
예제 #11
0
        public override void Prepare()
        {
            if ((db2Conn == null) || (db2Conn.State != ConnectionState.Open))
            {
                throw new InvalidOperationException("Prepare needs an open connection");
            }

            CloseStatementHandle(false);
            if (hwndStmt == IntPtr.Zero)
            {
                AllocateStatement("InternalExecuteNonQuery");
            }

            short sqlRet = 0;

            IntPtr numParams = IntPtr.Zero;

            sqlRet = DB2CLIWrapper.SQLPrepare(hwndStmt, commandText, commandText.Length);
            DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLPrepare error.", db2Conn);

            statementOpen = true;
            prepared      = true;
        }
예제 #12
0
        ///
        /// Bind this parameter
        ///
        internal short Bind(IntPtr hwndStmt, short paramNum)
        {
            int inLength = requiredMemory;

            db2LastUsedDataType = db2DataType;
            short db2CType = DB2Constants.SQL_C_DEFAULT;

            if ((direction == ParameterDirection.Input) || (direction == ParameterDirection.InputOutput))
            {
                if (Convert.IsDBNull(Value))
                {
                    inLength = DB2Constants.SQL_NULL_DATA;
                    if ((db2DataType == DB2Constants.SQL_UNKNOWN_TYPE) ||
                        (db2DataType == DB2Constants.SQL_DECIMAL))
                    {
                        db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;
                        db2CType            = DB2Constants.SQL_C_WCHAR;
                    }
                }
            }
            if ((direction == ParameterDirection.Input) || (direction == ParameterDirection.InputOutput))
            {
                switch (db2DataType)
                {
                case DB2Constants.SQL_WCHAR:
                    string tmpString = Convert.ToString(Value);
                    inLength = tmpString.Length;
                    if ((Size > 0) && (inLength > Size))
                    {
                        inLength = Size;
                    }
                    Marshal.Copy(tmpString.ToCharArray(), 0, internalBuffer, inLength);
                    inLength           *= 2;
                    db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;
                    db2CType            = DB2Constants.SQL_C_WCHAR;
                    if (inLength > 32000)
                    {
                        db2LastUsedDataType = DB2Constants.SQL_TYPE_BLOB;
                    }
                    break;

                case DB2Constants.SQL_VARBINARY:
                    byte[] tmpBytes = (byte[])Value;
                    inLength = tmpBytes.Length;
                    if ((Size > 0) && (inLength > Size))
                    {
                        inLength = Size;
                    }
                    Marshal.Copy(tmpBytes, 0, internalBuffer, inLength);
                    db2CType = DB2Constants.SQL_TYPE_BINARY;
                    break;

                case DB2Constants.SQL_BIT:
                case DB2Constants.SQL_UTINYINT:
                case DB2Constants.SQL_SMALLINT:
                    Marshal.WriteInt16(internalBuffer, Convert.ToInt16(Value));
                    db2CType = DB2Constants.SQL_C_SSHORT;
                    break;

                case DB2Constants.SQL_INTEGER:
                    Marshal.WriteInt32(internalBuffer, Convert.ToInt32(Value));
                    db2CType = DB2Constants.SQL_C_SLONG;
                    break;

                case DB2Constants.SQL_BIGINT:
                    Marshal.WriteInt64(internalBuffer, Convert.ToInt64(Value));
                    db2CType = DB2Constants.SQL_C_SBIGINT;
                    break;

                case DB2Constants.SQL_REAL:
                    Marshal.StructureToPtr((float)Convert.ToDouble(Value), internalBuffer, false);
                    db2CType = DB2Constants.SQL_C_TYPE_REAL;
                    break;

                case DB2Constants.SQL_DOUBLE:
                    Marshal.StructureToPtr(Convert.ToDouble(Value), internalBuffer, false);
                    db2CType = DB2Constants.SQL_C_DOUBLE;
                    break;

                case DB2Constants.SQL_DECIMAL:
                    byte[] tmpDecimalData = System.Text.Encoding.UTF8.GetBytes(
                        Convert.ToDecimal(Value).ToString(System.Globalization.CultureInfo.InvariantCulture));
                    inLength = Math.Min(tmpDecimalData.Length, requiredMemory);
                    Marshal.Copy(tmpDecimalData, 0, internalBuffer, inLength);
                    db2LastUsedDataType = DB2Constants.SQL_VARCHAR;
                    db2CType            = DB2Constants.SQL_C_CHAR;
                    break;

                case DB2Constants.SQL_TYPE_DATE:
                    DateTime tmpDate = Convert.ToDateTime(Value);
                    Marshal.WriteInt16(internalBuffer, 0, (short)tmpDate.Year);
                    Marshal.WriteInt16(internalBuffer, 2, (short)tmpDate.Month);
                    Marshal.WriteInt16(internalBuffer, 4, (short)tmpDate.Day);
                    db2CType = DB2Constants.SQL_C_TYPE_DATE;
                    break;

                case DB2Constants.SQL_TYPE_TIMESTAMP:
                    DateTime tmpDateTime = Convert.ToDateTime(Value);
                    Marshal.WriteInt16(internalBuffer, 0, (short)tmpDateTime.Year);
                    Marshal.WriteInt16(internalBuffer, 2, (short)tmpDateTime.Month);
                    Marshal.WriteInt16(internalBuffer, 4, (short)tmpDateTime.Day);
                    Marshal.WriteInt16(internalBuffer, 6, (short)tmpDateTime.Hour);
                    Marshal.WriteInt16(internalBuffer, 8, (short)tmpDateTime.Minute);
                    Marshal.WriteInt16(internalBuffer, 10, (short)tmpDateTime.Second);
                    Marshal.WriteInt32(internalBuffer, 12, (int)((tmpDateTime.Ticks % 10000000) * 100));
                    db2CType = DB2Constants.SQL_C_TYPE_TIMESTAMP;
                    break;

                case DB2Constants.SQL_TYPE_TIME:
                    TimeSpan tmpTime = (TimeSpan)Value;
                    Marshal.WriteInt16(internalBuffer, 0, (short)tmpTime.Hours);
                    Marshal.WriteInt16(internalBuffer, 2, (short)tmpTime.Minutes);
                    Marshal.WriteInt16(internalBuffer, 4, (short)tmpTime.Seconds);
                    db2CType = DB2Constants.SQL_C_TYPE_TIME;
                    break;
                }
            }
            else
            {
                switch (db2DataType)
                {
                case DB2Constants.SQL_WCHAR:
                    db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;
                    db2CType            = DB2Constants.SQL_C_WCHAR;
                    break;

                case DB2Constants.SQL_VARBINARY:
                    db2CType = DB2Constants.SQL_TYPE_BINARY;
                    break;

                case DB2Constants.SQL_BIT:
                case DB2Constants.SQL_UTINYINT:
                case DB2Constants.SQL_SMALLINT:
                    db2CType = DB2Constants.SQL_C_SSHORT;
                    break;

                case DB2Constants.SQL_INTEGER:
                    db2CType = DB2Constants.SQL_C_SLONG;
                    break;

                case DB2Constants.SQL_BIGINT:
                    db2CType = DB2Constants.SQL_C_SBIGINT;
                    break;

                case DB2Constants.SQL_REAL:
                    db2CType = DB2Constants.SQL_C_TYPE_REAL;
                    break;

                case DB2Constants.SQL_DOUBLE:
                    db2CType = DB2Constants.SQL_C_DOUBLE;
                    break;

                case DB2Constants.SQL_DECIMAL:
                    db2LastUsedDataType = DB2Constants.SQL_VARCHAR;
                    db2CType            = DB2Constants.SQL_C_CHAR;
                    break;

                case DB2Constants.SQL_TYPE_DATE:
                    db2CType = DB2Constants.SQL_C_TYPE_DATE;
                    break;

                case DB2Constants.SQL_TYPE_TIMESTAMP:
                    db2CType = DB2Constants.SQL_C_TYPE_TIMESTAMP;
                    break;

                case DB2Constants.SQL_TYPE_TIME:
                    db2CType = DB2Constants.SQL_C_TYPE_TIME;
                    break;
                }
            }
            Marshal.WriteInt32(internalLengthBuffer, inLength);
            short sqlRet = DB2CLIWrapper.SQLBindParameter(hwndStmt, paramNum, db2Direction,
                                                          db2CType, db2LastUsedDataType, Size, Scale,
                                                          internalBuffer, requiredMemory, internalLengthBuffer);

            return(sqlRet);
        }
        public DB2OpenConnection(DB2ConnectionSettings settings, DB2Connection connection)
        {
            this.settings = settings;
            try
            {
                short sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_DBC, DB2Environment.Instance.penvHandle, out dbHandle);
                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, DB2Environment.Instance.penvHandle, "Unable to allocate database handle in DB2Connection.", connection);

                if (settings.Server.Length > 0)
                {
                    StringBuilder outConnectStr = new StringBuilder(60); // TODO: ????
                    short         numOutCharsReturned;

                    sqlRet = DB2CLIWrapper.SQLDriverConnect(dbHandle, IntPtr.Zero,
                                                            settings.ConnectionString, (short)settings.ConnectionString.Length,
                                                            outConnectStr, (short)outConnectStr.Length, out numOutCharsReturned,
                                                            DB2Constants.SQL_DRIVER_NOPROMPT /*SQL_DRIVER_COMPLETE*/);
                }
                else
                {
                    sqlRet = DB2CLIWrapper.SQLConnect(dbHandle,
                                                      settings.DatabaseAlias, (short)settings.DatabaseAlias.Length,
                                                      settings.UserName, (short)settings.UserName.Length,
                                                      settings.PassWord, (short)settings.PassWord.Length);
                    DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, dbHandle, "Unable to connect to the database.", connection);
                }

                if ((settings.Pool == null) || (settings.Pool.databaseProductName == null))
                {
                    StringBuilder sb = new StringBuilder(256);
                    short         stringLength;
                    sqlRet = DB2CLIWrapper.SQLGetInfo(dbHandle, /*SQL_DBMS_NAME*/ 17, sb, (short)(sb.Capacity / 2), out stringLength);
                    new DB2ErrorCollection(DB2Constants.SQL_HANDLE_DBC, dbHandle).ToString();
                    if (sqlRet == 0)
                    {
                        databaseProductName = sb.ToString(0, Math.Min(sb.Capacity, stringLength / 2));
                    }
                    sqlRet = DB2CLIWrapper.SQLGetInfo(dbHandle, /*SQL_DBMS_VER*/ 18, sb, (short)(sb.Capacity / 2), out stringLength);
                    if (sqlRet == 0)
                    {
                        databaseVersion = sb.ToString(0, Math.Min(sb.Capacity, stringLength / 2));
                        try
                        {
                            string[] splitVersion = databaseVersion.Split('.');
                            majorVersion = int.Parse(splitVersion[0]);
                            minorVersion = int.Parse(splitVersion[1]);
                        }
                        catch {}
                    }
                    if (settings.Pool != null)
                    {
                        settings.Pool.databaseProductName = databaseProductName;
                        settings.Pool.databaseVersion     = databaseVersion;
                        settings.Pool.majorVersion        = majorVersion;
                        settings.Pool.minorVersion        = minorVersion;
                    }
                }
                else if (settings.Pool != null)
                {
                    if (settings.Pool != null)
                    {
                        databaseProductName = settings.Pool.databaseProductName;
                        databaseVersion     = settings.Pool.databaseVersion;
                        majorVersion        = settings.Pool.majorVersion;
                        minorVersion        = settings.Pool.minorVersion;
                    }
                }
            }
            catch
            {
                if (dbHandle != IntPtr.Zero)
                {
                    DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_DBC, dbHandle);
                    dbHandle = IntPtr.Zero;
                }
                throw;
            }
        }
 public void RollbackDeadTransaction()
 {
     DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, DBHandle, DB2Constants.SQL_ROLLBACK);
     transactionOpen = false;
 }
예제 #15
0
        public void ExecuteNonQueryInternal(CommandBehavior behavior)
        {
            short sqlRet;

            if (prepared && binded)
            {
                sqlRet = DB2CLIWrapper.SQLExecute(hwndStmt);
                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecute error.", db2Conn);
                return;
            }

            if ((db2Conn == null) || (db2Conn.State != ConnectionState.Open))
            {
                throw new InvalidOperationException("Prepare needs an open connection");
            }
            if ((refDataReader != null) &&
                (refDataReader.IsAlive))
            {
                throw new InvalidOperationException("There is already an open DataReader associated with this Connection which must be closed first.");
            }
            DB2Transaction connectionTransaction = null;

            if (db2Conn.WeakRefTransaction != null)
            {
                connectionTransaction = (DB2Transaction)db2Conn.WeakRefTransaction.Target;
            }
            if (!Object.ReferenceEquals(connectionTransaction, Transaction))
            {
                if (Transaction == null)
                {
                    throw new InvalidOperationException("A transaction was started in the connection, but the command doesn't specify a transaction");
                }
                throw new InvalidOperationException("The transaction specified at the connection doesn't belong to the connection");
            }

            if (hwndStmt == IntPtr.Zero)
            {
                AllocateStatement("InternalExecuteNonQuery");
                previousBehavior = 0;
            }
            if (previousBehavior != behavior)
            {
                if (((previousBehavior ^ behavior) & CommandBehavior.SchemaOnly) != 0)
                {
                    sqlRet = DB2CLIWrapper.SQLSetStmtAttr(hwndStmt, DB2Constants.SQL_ATTR_DEFERRED_PREPARE,
                                                          new IntPtr((behavior & CommandBehavior.SchemaOnly) != 0 ? 0 : 1), 0);
                    // TODO: don't check. what if it is not supported???
                    DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Defered prepare.", db2Conn);

                    previousBehavior = (previousBehavior & ~CommandBehavior.SchemaOnly) | (behavior & CommandBehavior.SchemaOnly);
                }
                if (((previousBehavior ^ behavior) & CommandBehavior.SingleRow) != 0)
                {
                    sqlRet = DB2CLIWrapper.SQLSetStmtAttr(hwndStmt, DB2Constants.SQL_ATTR_MAX_ROWS,
                                                          new IntPtr((behavior & CommandBehavior.SingleRow) == 0 ? 0 : 1), 0);
                    // TODO: don't check. what if it is not supported???
                    DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Set max rows", db2Conn);

                    previousBehavior = (previousBehavior & ~CommandBehavior.SingleRow) | (behavior & CommandBehavior.SingleRow);
                }
                previousBehavior = behavior;
            }
            if ((Transaction == null) &&
                !db2Conn.openConnection.autoCommit)
            {
                sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_AUTOCOMMIT, new IntPtr(DB2Constants.SQL_AUTOCOMMIT_ON), 0);
                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting AUTOCOMMIT ON in transaction CTOR.", db2Conn);
                db2Conn.openConnection.autoCommit = true;

                sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_TXN_ISOLATION, new IntPtr(DB2Constants.SQL_TXN_READ_COMMITTED), 0);
                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting isolation level.", db2Conn);
            }


            if ((commandText == null) || (commandText.Length == 0))
            {
                throw new InvalidOperationException("Command string is empty");
            }

            if (CommandType.StoredProcedure == commandType && !commandText.StartsWith("CALL "))
            {
                commandText = "CALL " + commandText + " ()";
            }

            if ((behavior & CommandBehavior.SchemaOnly) != 0)
            {
                if (!prepared)
                {
                    Prepare();
                }
            }
            else
            {
                if (statementParametersMemory != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(statementParametersMemory);
                    statementParametersMemory = IntPtr.Zero;
                }

                BindParams();

                if (prepared)
                {
                    sqlRet = DB2CLIWrapper.SQLExecute(hwndStmt);
                    DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecute error.", db2Conn);
                }
                else
                {
                    sqlRet = DB2CLIWrapper.SQLExecDirect(hwndStmt, commandText, commandText.Length);
                    DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecDirect error.", db2Conn);
                }
                statementOpen = true;

                parameters.GetOutValues();

                if (statementParametersMemory != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(statementParametersMemory);
                    statementParametersMemory = IntPtr.Zero;
                }
            }
        }
예제 #16
0
        private void SetStatementTimeout()
        {
            short sqlRet = DB2CLIWrapper.SQLSetStmtAttr(hwndStmt, DB2Constants.SQL_ATTR_QUERY_TIMEOUT, new IntPtr(commandTimeout), 0);

            DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Set statement timeout.", db2Conn);
        }