Exemple #1
0
        public virtual object Clone()
        {
            AbstractDbParameter other = (AbstractDbParameter)MemberwiseClone();

            other._parent = null;
            return(other);
        }
        void Validate(int index, object value)
        {
            ValidateType(value);
            AbstractDbParameter parameter = (AbstractDbParameter)value;

            if (parameter.Parent != null)
            {
                if (parameter.Parent.Equals(this))
                {
                    if (IndexOf(parameter) != index)
                    {
                        throw ExceptionHelper.CollectionAlreadyContains(ItemType, "ParameterName", parameter.ParameterName, this);
                    }
                }
                else
                {
                    // FIXME :  The OleDbParameter with ParameterName 'MyParam2' is already contained by another OleDbParameterCollection.
                    throw new ArgumentException("");
                }
            }

            if (parameter.ParameterName == null || parameter.ParameterName == String.Empty)
            {
                int    newIndex = 1;
                string parameterName;

                do
                {
                    parameterName = "Parameter" + newIndex;
                    newIndex++;
                }while(IndexOf(parameterName) != -1);

                parameter.ParameterName = parameterName;
            }
        }
        private void RemoveIndex(int index)
        {
            OnSchemaChanging();
            AbstractDbParameter oldItem = (AbstractDbParameter)_list [index];

            oldItem.Parent = null;
            _list.RemoveAt(index);
        }
Exemple #4
0
		int PrepareSimpleQuery(StringBuilder sb, string query, IList userParametersList, int userParametersListStart)
		{
			int queryCurrentPosition = 0;
			int userParametersListPosition = userParametersListStart;

			if (userParametersList.Count > 0) {
				for (SimpleMatch m = ParameterRegExp.Match(query);
					m.Success;m = m.NextMatch()) {

					SimpleCapture parameterCapture = m;
					sb.Append(query,queryCurrentPosition,parameterCapture.Index - queryCurrentPosition);

					// advance in query
					queryCurrentPosition = parameterCapture.Index + parameterCapture.Length;	

					AbstractDbParameter userParameter = GetUserParameter(parameterCapture.Value, userParametersList, userParametersListPosition);

					if (userParameter != null) {
						if (IsNullParameter(userParameter)) {
							sb.Append("null");
							NullParametersInPrepare = true;
						}
						else {
							sb.Append('?');
							InternalParameters.Add(userParameter);	
						}	
						// advance in user parameters
						userParametersListPosition++;				
					}
					else {
						sb.Append(parameterCapture.Value);
					}
				}
			}

			sb.Append(query,queryCurrentPosition,query.Length - queryCurrentPosition);
			int userParamsConsumed = userParametersListPosition - userParametersListStart;

			if ((Behavior & CommandBehavior.KeyInfo) == 0)
				return userParamsConsumed;

			AbstractDBConnection connection = (AbstractDBConnection)Connection;
			if (connection == null)
				return userParamsConsumed;

			string dbname = connection.JdbcConnection.getMetaData().getDatabaseProductName();
			if (dbname == "Microsoft SQL Server") {	//must add "FOR BROWSE" for selects
#if USE_DOTNET_REGEX
					if (!SqlStatementsHelper.ForBrowseStatementReqExp.IsMatch(query))
						sb.Append(" FOR BROWSE");
#else
					if (!SqlStatementsHelper.ForBrowseStatementReqExp.matcher ((java.lang.CharSequence)(object)query).find ())
						sb.Append (" FOR BROWSE");
#endif
			}

			return userParamsConsumed;
		}
Exemple #5
0
		protected virtual AbstractDbParameter GetReturnParameter (IList userParametersList)
		{
			AbstractDbParameter param = GetUserParameter ("?", userParametersList, 0); 

			if (param != null && param.Direction == ParameterDirection.ReturnValue)
				return param;

			return null;
		}
Exemple #6
0
		protected virtual AbstractDbParameter GetUserParameter(string parameterName, IList userParametersList, int userParametersListPosition)
		{
			if (userParametersListPosition < userParametersList.Count) {
				AbstractDbParameter param = (AbstractDbParameter)userParametersList[userParametersListPosition];
				if (param.Placeholder == parameterName)
					return param;
			}
			return null;
		}
        private void Replace(int index, DbParameter value)
        {
            Validate(index, value);
            AbstractDbParameter oldItem = (AbstractDbParameter)this [index];

            oldItem.Parent = null;

            ((AbstractDbParameter)value).Parent = this;
            _list [index] = value;
        }
Exemple #8
0
		private void FillOutputParameters()
		{	
			if  (!(_statement is CallableStatement)) {
				return;
			}
			for(int i = 0; i < InternalParameters.Count; i++) {
				AbstractDbParameter parameter = (AbstractDbParameter)InternalParameters[i];
				ParameterDirection direction = parameter.Direction;
				if (((direction & ParameterDirection.Output) != 0) && !SkipParameter(parameter)) {					
					FillOutputParameter(parameter, i);
				}
				// drop jdbc type of out parameter, since it possibly was updated in ExecuteReader
				parameter.IsJdbcTypeSet = false;
			}
		}
Exemple #9
0
		protected void BindParameters(ArrayList parameters)
		{
			for(int parameterIndex = 0; parameterIndex < parameters.Count; parameterIndex++) {
				AbstractDbParameter parameter = (AbstractDbParameter)parameters[parameterIndex];
				switch (parameter.Direction) {
					case ParameterDirection.Input :
						BindInputParameter(parameter,parameterIndex);
						break;
					case ParameterDirection.InputOutput:
						BindInputParameter(parameter,parameterIndex);
						BindOutputParameter(parameter,parameterIndex);
						break;
					case ParameterDirection.Output :
						BindOutputParameter(parameter,parameterIndex);
						break;
					case ParameterDirection.ReturnValue :
						BindOutputParameter(parameter,parameterIndex);
						break;
				}
			}
		}
Exemple #10
0
		protected virtual void BindOutputParameter(AbstractDbParameter parameter, int parameterIndex)
		{
			parameter.Validate();
			int jdbcType = (int)parameter.JdbcType;		
			// java parameters are 1 based, while .net are 0 based
			parameterIndex++;

			CallableStatement callableStatement = ((CallableStatement)_statement);

			// the scale has a meening only in DECIMAL and NUMERIC parameters
			if (jdbcType == Types.DECIMAL || jdbcType == Types.NUMERIC) {
				if(parameter.DbType == DbType.Currency) {
					callableStatement.registerOutParameter(parameterIndex, jdbcType, 4);
				}
				else {
					callableStatement.registerOutParameter(parameterIndex, jdbcType, parameter.Scale);
				}
			}
			else {
				callableStatement.registerOutParameter(parameterIndex, jdbcType);
			}
		}
Exemple #11
0
		protected virtual void BindInputParameter(AbstractDbParameter parameter, int parameterIndex)
		{
			object value = parameter.ConvertedValue;			
			// java parameters are 1 based, while .net are 0 based
			parameterIndex++; 
			PreparedStatement preparedStatement = ((PreparedStatement)_statement);

			switch ((DbConvert.JavaSqlTypes)parameter.JdbcType) {
				case DbConvert.JavaSqlTypes.DATALINK:
				case DbConvert.JavaSqlTypes.DISTINCT:
				case DbConvert.JavaSqlTypes.JAVA_OBJECT:
				case DbConvert.JavaSqlTypes.OTHER:
				case DbConvert.JavaSqlTypes.REF:
				case DbConvert.JavaSqlTypes.STRUCT: {
					preparedStatement.setObject(parameterIndex, value, (int)parameter.JdbcType);
					return;
				}
			}

			if ((value is DBNull) || (value == null)) {
				preparedStatement.setNull(parameterIndex, (int)((AbstractDbParameter)parameter).JdbcType);
			}
			else if (value is long) {
				preparedStatement.setLong(parameterIndex, (long)value);
			}
			else if (value is byte[]) {
				if (((byte[])value).Length <= 4000) {
					preparedStatement.setBytes(parameterIndex, vmw.common.TypeUtils.ToSByteArray((byte[]) value));
				}
				else {
					InputStream iStream=new ByteArrayInputStream(vmw.common.TypeUtils.ToSByteArray((byte[]) value));
					preparedStatement.setBinaryStream(parameterIndex,iStream,((byte[])value).Length);
				}
			}
			else if (value is byte) {
				preparedStatement.setByte(parameterIndex, (sbyte)(byte)value);
			}
			else if (value is char[]) {
				Reader reader = new CharArrayReader((char[])value);
				preparedStatement.setCharacterStream(parameterIndex,reader,((char[])value).Length);
			}
			else if (value is bool) {
				preparedStatement.setBoolean(parameterIndex, (bool) value);
			}
			else if (value is char) {
				preparedStatement.setString(parameterIndex, ((char)value).ToString());
			}
			else if (value is DateTime) {
				switch ((DbConvert.JavaSqlTypes)parameter.JdbcType) {
					default:
					case DbConvert.JavaSqlTypes.TIMESTAMP:
						preparedStatement.setTimestamp(parameterIndex,DbConvert.ClrTicksToJavaTimestamp(((DateTime)value).Ticks));
						break;
					case DbConvert.JavaSqlTypes.TIME:
						preparedStatement.setTime(parameterIndex,DbConvert.ClrTicksToJavaTime(((DateTime)value).Ticks));
						break;
					case DbConvert.JavaSqlTypes.DATE:
						preparedStatement.setDate(parameterIndex,DbConvert.ClrTicksToJavaDate(((DateTime)value).Ticks));
						break;
				}
			}
			else if (value is TimeSpan) {
				if (parameter.JdbcType == (int)DbConvert.JavaSqlTypes.TIMESTAMP)
					preparedStatement.setTimestamp(parameterIndex,DbConvert.ClrTicksToJavaTimestamp(((TimeSpan)value).Ticks));
				else
					preparedStatement.setTime(parameterIndex,DbConvert.ClrTicksToJavaTime(((TimeSpan)value).Ticks));
			}
			else if (value is Decimal) {
				preparedStatement.setBigDecimal(parameterIndex, vmw.common.PrimitiveTypeUtils.DecimalToBigDecimal((Decimal) value));
			}
			else if (value is double) {
				preparedStatement.setDouble(parameterIndex, (double)value);
			}
			else if (value is float) {
				preparedStatement.setFloat(parameterIndex, (float)value);
			}
			else if (value is int) {
				preparedStatement.setInt(parameterIndex, (int)value);
			}
			else if (value is string) {
				//can not be done for inout params, due to Oracle problem with FIXED_CHAR out param fetching
				if (parameter.Direction == ParameterDirection.Input && 
					preparedStatement is Mainsoft.Data.Jdbc.Providers.IPreparedStatement &&
					(DbConvert.JavaSqlTypes)parameter.JdbcType == DbConvert.JavaSqlTypes.CHAR) {
					((Mainsoft.Data.Jdbc.Providers.IPreparedStatement)preparedStatement)
						.setChar(parameterIndex, (string)value);
				}
				else
					preparedStatement.setString(parameterIndex, (string)value);
			}
			else if (value is Guid) {
				preparedStatement.setString(parameterIndex, value.ToString());
			}
			else if (value is short) {
				preparedStatement.setShort(parameterIndex, (short)value);
			}
			else if (value is sbyte) {
				preparedStatement.setByte(parameterIndex, (sbyte)value);
			}
			else {
				preparedStatement.setObject(parameterIndex, value);
			}
		}
Exemple #12
0
		private void PrepareInternal()
		{
			if ((Connection == null) || (Connection.State != ConnectionState.Open)) {
				throw ExceptionHelper.ConnectionNotOpened("Prepare",(Connection != null) ? Connection.State.ToString() : "");
			}

			if (IsCommandPrepared) {
				// maybe we have to prepare the command again
				bool hasNullParameters = false;
				for(int i = 0; (i < Parameters.Count) && !hasNullParameters; i++) {
					AbstractDbParameter parameter = (AbstractDbParameter)Parameters[i];
					if (IsNullParameter(parameter)) {
						// if we still have null parameters - have to prepare agail
						IsCommandPrepared = false;
						hasNullParameters = true;
					}
				}

				if (!NullParametersInPrepare && hasNullParameters) {
					// if we prepeared using null parameters and now there is no null parameters - need to prepare again
					IsCommandPrepared = false;
				}
			}

			if (!IsCommandPrepared) {

				_javaCommandText = PrepareCommandTextAndParameters();

				java.sql.Connection jdbcCon = _connection.JdbcConnection;

				// For SchemaOnly we just prepare statement (for future use in GetSchemaTable)
				if (Behavior == CommandBehavior.SchemaOnly) {
					if (CommandType == CommandType.StoredProcedure)
						_statement = jdbcCon.prepareCall(_javaCommandText);
					else
						_statement = jdbcCon.prepareStatement(_javaCommandText);	
					return;
				}

				if (CommandType == CommandType.StoredProcedure)
					_statement = jdbcCon.prepareCall(_javaCommandText);
				else {
					int internalParametersCount = InternalParameters.Count;
					if ( internalParametersCount > 0) {
						bool hasOnlyInputParameters = true;
						for(int i=0; i < internalParametersCount; i++) {
							AbstractDbParameter internalParameter = (AbstractDbParameter)InternalParameters[i];
							if (IsNullParameter(internalParameter)) {
								NullParametersInPrepare = true;
							}

							if ((internalParameter.Direction & ParameterDirection.Output) != 0){
								hasOnlyInputParameters = false;
							}
						}

						if (hasOnlyInputParameters) {
							_statement = jdbcCon.prepareStatement(_javaCommandText);	
						}
						else {						
							_statement = jdbcCon.prepareCall(_javaCommandText);
						}
					}
					else {
						if (_explicitPrepare) {
							_statement = jdbcCon.prepareStatement(_javaCommandText);				
						}
						else {
							_statement = jdbcCon.createStatement();					
						}
					}
				}
				IsCommandPrepared = true;
			}
		}
Exemple #13
0
		int CreateStoredProcedureCommandText(StringBuilder sb, string sql, Matcher match, IDataParameterCollection userParams, int userParamsStartPosition)
#endif
		{
			int curUserPos = userParamsStartPosition;
#if USE_DOTNET_REGEX
			Group procNameGroup = null;

			for (Match procNameMatch = match; procNameMatch.Success; procNameMatch = procNameMatch.NextMatch()){
				procNameGroup = match.Groups["PROCNAME"];
				if (!procNameGroup.Success) {
					continue;
				}
			}

			if (procNameGroup == null || !procNameGroup.Success)
				throw new ArgumentException("Not a stored procedure call: '{0}'", sql);

			ArrayList derivedParameters = DeriveParameters(procNameGroup.Value, false);
#else
			ArrayList derivedParameters = DeriveParameters(match.group(2).Trim(), false);
#endif
			int curDerivedPos = 0;

			AbstractDbParameter retValderivedParameter = curDerivedPos < derivedParameters.Count ?
				(AbstractDbParameter)derivedParameters[curDerivedPos] : null;
			if (retValderivedParameter != null && retValderivedParameter.Direction == ParameterDirection.ReturnValue)
				curDerivedPos++;

			int queryCurrentPosition = 0;
			
#if USE_DOTNET_REGEX
			for (Match retValMatch = match; retValMatch.Success; retValMatch = retValMatch.NextMatch()){
				Group retval = retValMatch.Groups["RETVAL"];
				if (!retval.Success) {
					continue;
				}

				int retvalIndex = retval.Index;
				string retvalValue = retval.Value;
				int retvalLength = retval.Length;
#else
			int retvalIndex = match.start(1);
			for (;retvalIndex >= 0;) {
				string retvalValue = match.group(1);
				int retvalLength = retvalValue.Length;
#endif

				sb.Append(sql, queryCurrentPosition, retvalIndex);
				AbstractDbParameter userParameter = GetUserParameter(retvalValue, userParams, curUserPos);
				if (userParameter != null) {
					sb.Append('?');
					InternalParameters.Add(userParameter);

					if (retValderivedParameter != null && !userParameter.IsDbTypeSet) {
						userParameter.JdbcType = retValderivedParameter.JdbcType;
					}

					curUserPos++;
				}
				else {
					sb.Append(retvalValue);
				}

				queryCurrentPosition = (retvalIndex + retvalLength);

				break;
			}

#if USE_DOTNET_REGEX
			sb.Append(sql, queryCurrentPosition, procNameGroup.Index + procNameGroup.Length - queryCurrentPosition);
			queryCurrentPosition = procNameGroup.Index + procNameGroup.Length;
#else
			sb.Append(sql, queryCurrentPosition, match.end(2) - queryCurrentPosition);
			queryCurrentPosition = match.end(2);
#endif

			bool hasUserParams = false;

#if USE_DOTNET_REGEX
			must rewrite the regex to not parse params to have single code with java regex
#else
			int paramsStart = match.start(3);
			if (paramsStart >= 0) {
#endif

				hasUserParams = true;
				sb.Append(sql,queryCurrentPosition,paramsStart - queryCurrentPosition);
				queryCurrentPosition = paramsStart;

				for (SimpleMatch m = SqlStatementsHelper.ProcedureParameterSplitterReqExp.Match(match.group(3));
					m.Success;m = m.NextMatch()) {

					SimpleCapture parameterCapture = m;
					sb.Append(sql,queryCurrentPosition,paramsStart + parameterCapture.Index - queryCurrentPosition);

					// advance in query
					queryCurrentPosition = paramsStart + parameterCapture.Index + parameterCapture.Length;

					AbstractDbParameter derivedParameter = curDerivedPos < derivedParameters.Count ?
						(AbstractDbParameter)derivedParameters[curDerivedPos++] : null;
					
					//check for special params
					while (derivedParameter != null && derivedParameter.IsSpecial) {
						// derived parameter is special - never appears in user parameters or user values
						InternalParameters.Add((AbstractDbParameter)derivedParameter.Clone());
						sb.Append('?');
						sb.Append(',');

						derivedParameter = curDerivedPos < derivedParameters.Count ?
							(AbstractDbParameter)derivedParameters[curDerivedPos++] : null;
					}

					AbstractDbParameter userParameter = GetUserParameter(parameterCapture.Value.Trim(), userParams, curUserPos);

					if (userParameter != null) {
						sb.Append('?');
						InternalParameters.Add(userParameter);
						if (derivedParameter != null && !userParameter.IsDbTypeSet) {
							userParameter.JdbcType = derivedParameter.JdbcType;
						}
						// advance in user parameters
						curUserPos++;				
					}
					else {
						sb.Append(parameterCapture.Value);
					}									
				}					
			}

			bool addedSpecialParams = false;

			for (int i = curDerivedPos; i < derivedParameters.Count;) {
				AbstractDbParameter derivedParameter = (AbstractDbParameter)derivedParameters[i++];
				if (derivedParameter.IsSpecial) {
					// derived parameter is special - never appears in user parameters or user values
					if (!hasUserParams && !addedSpecialParams) {
						addedSpecialParams = true;
						curDerivedPos++;
						sb.Append('(');
					}

					for (;curDerivedPos < i;curDerivedPos++)
						sb.Append(',');

					InternalParameters.Add((AbstractDbParameter)derivedParameter.Clone());
					sb.Append('?');
				}
			}

			if (!hasUserParams && addedSpecialParams)
				sb.Append(')');

			sb.Append(sql,queryCurrentPosition,sql.Length - queryCurrentPosition);
			return curUserPos - userParamsStartPosition;
		}
Exemple #14
0
		string CreateStoredProcedureCommandTextSimple(string procedureName, IDataParameterCollection userParams, IList derivedParams) {
			StringBuilder sb = new StringBuilder();

			int curUserPos = 0;
			int curDerivedPos = 0;
			bool addParas = true;
			string trimedProcedureName = (procedureName != null) ? procedureName.TrimEnd() : String.Empty;
			if (trimedProcedureName.Length > 0 && trimedProcedureName[trimedProcedureName.Length-1] == ')')
				addParas = false;
			
				AbstractDbParameter derivedParam = (derivedParams.Count > 0) ? (AbstractDbParameter)derivedParams[curDerivedPos] : null;
				if (derivedParam != null) {
					if (derivedParam.Direction == ParameterDirection.ReturnValue)
						curDerivedPos++;
					else
						derivedParam = null; //play as if there is no retval parameter
				}
				AbstractDbParameter returnValueParameter = GetReturnParameter (userParams);
				if (returnValueParameter != null) {
					curUserPos++;
					InternalParameters.Add(returnValueParameter);
					sb.Append("{? = call ");

					if (derivedParam != null && !returnValueParameter.IsDbTypeSet) {
						returnValueParameter.JdbcType = derivedParam.JdbcType;
					}
				}
				else {
					sb.Append("{call ");
				}

			sb.Append(procedureName);
			if (addParas)
				sb.Append('(');

			bool needComma = false;
			for (int i = curDerivedPos; i < derivedParams.Count; i++) {
				AbstractDbParameter derivedParameter = (AbstractDbParameter)derivedParams[curDerivedPos++];
				
				bool addParam = false;

				if (derivedParameter.IsSpecial) {
					// derived parameter is special - never appears in user parameters or user values
					InternalParameters.Add((AbstractDbParameter)derivedParameter.Clone());
					addParam = true;
				}
				else {
					AbstractDbParameter userParameter = GetUserParameter(derivedParameter.Placeholder, userParams, curUserPos);
					if (userParameter != null) {
						curUserPos++;
						InternalParameters.Add(userParameter);
						addParam = true;

						if (derivedParameter != null && !userParameter.IsDbTypeSet) {
							userParameter.JdbcType = derivedParameter.JdbcType;
						}
					}
				}

				if (addParam) {
					if (needComma)
						sb.Append(',');
					else
						needComma = true;

					sb.Append('?');
				}
			}

			for (int i = curUserPos; i < userParams.Count; i++) {
				if (needComma)
					sb.Append(',');
				else
					needComma = true;

				AbstractDbParameter userParameter = (AbstractDbParameter)userParams[curUserPos++];
				InternalParameters.Add(userParameter);

				sb.Append('?');
			}

			if (addParas)
				sb.Append(')');
			sb.Append('}');
			return sb.ToString();
		}
Exemple #15
0
		protected virtual bool IsNullParameter(AbstractDbParameter parameter)
		{
			return ((parameter.Value == null || parameter.Value == DBNull.Value) && !parameter.IsDbTypeSet);
		}
		protected override void BindOutputParameter(AbstractDbParameter parameter, int parameterIndex)
		{
			CallableStatement callableStatement = ((CallableStatement)Statement);
			if (((OleDbParameter)parameter).IsOracleRefCursor) {
				callableStatement.registerOutParameter(++parameterIndex, _oracleRefCursor);
			}
			else {
				base.BindOutputParameter(parameter, parameterIndex);
			}
		}
        internal ArrayList GetProcedureColumns(String procedureString, AbstractDbCommand command)
        {
            ArrayList col = new ArrayList();

            try
            {
                ObjectNameResolver[] nameResolvers = SyntaxPatterns;
                java.sql.ResultSet   res           = null;
                string catalog = null;
                string schema  = null;
                string spname  = null;

                java.sql.DatabaseMetaData metadata = JdbcConnection.getMetaData();
                bool storesUpperCaseIdentifiers    = false;
                bool storesLowerCaseIdentifiers    = false;
                try
                {
                    storesUpperCaseIdentifiers = metadata.storesUpperCaseIdentifiers();
                    storesLowerCaseIdentifiers = metadata.storesLowerCaseIdentifiers();
                }
                catch (SQLException e)
                {
                    // suppress
                }

                for (int i = 0; i < nameResolvers.Length; i++)
                {
                    ObjectNameResolver nameResolver = nameResolvers[i];
                    Match match = nameResolver.Match(procedureString);

                    if (match.Success)
                    {
                        spname  = ObjectNameResolver.GetName(match);
                        schema  = ObjectNameResolver.GetSchema(match);
                        catalog = ObjectNameResolver.GetCatalog(match);

                        // make all identifiers uppercase or lowercase according to database metadata
                        if (storesUpperCaseIdentifiers)
                        {
                            spname  = (spname.Length > 0) ? spname.ToUpper() : null;
                            schema  = (schema.Length > 0) ? schema.ToUpper() : null;
                            catalog = (catalog.Length > 0) ? catalog.ToUpper() : null;
                        }
                        else if (storesLowerCaseIdentifiers)
                        {
                            spname  = (spname.Length > 0) ? spname.ToLower() : null;
                            schema  = (schema.Length > 0) ? schema.ToLower() : null;
                            catalog = (catalog.Length > 0) ? catalog.ToLower() : null;
                        }
                        else
                        {
                            spname  = (spname.Length > 0) ? spname : null;
                            schema  = (schema.Length > 0) ? schema : null;
                            catalog = (catalog.Length > 0) ? catalog : null;
                        }

                        // catalog from db is always in correct caps
                        if (catalog == null)
                        {
                            catalog = JdbcConnection.getCatalog();
                        }

                        try
                        {
                            // always get the first procedure that db returns
                            res = metadata.getProcedures(catalog, schema, spname);
                            if (res.next())
                            {
                                catalog = res.getString(1);
                                schema  = res.getString(2);
                                spname  = res.getString(3);
                                break;
                            }

                            spname = null;
                        }
                        catch // suppress exception
                        {
                            return(null);
                        }
                        finally
                        {
                            if (res != null)
                            {
                                res.close();
                            }
                        }
                    }
                }

                if (spname == null || spname.Length == 0)
                {
                    return(null);
                }

                try
                {
                    // get procedure columns based o  procedure metadata
                    res = metadata.getProcedureColumns(catalog, schema, spname, null);
                    while (res.next())
                    {
                        // since there is still a possibility that some of the parameters to getProcedureColumn were nulls,
                        // we need to filter the results with strict matching
                        if ((res.getString(1) != catalog) || (res.getString(2) != schema) || (res.getString(3) != spname))
                        {
                            continue;
                        }

                        AbstractDbParameter parameter = (AbstractDbParameter)command.CreateParameter();

                        parameter.SetParameterName(res);
                        parameter.SetParameterDbType(res);
                        parameter.SetSpecialFeatures(res);

                        //get parameter direction
                        short direction = res.getShort("COLUMN_TYPE");
                        if (direction == 1) //DatabaseMetaData.procedureColumnIn
                        {
                            parameter.Direction = ParameterDirection.Input;
                        }
                        else if (direction == 2) //DatabaseMetaData.procedureColumnInOut
                        {
                            parameter.Direction = ParameterDirection.InputOutput;
                        }
                        else if (direction == 4) //DatabaseMetaData.procedureColumnOut
                        {
                            parameter.Direction = ParameterDirection.Output;
                        }
                        else if (direction == 5) //DatabaseMetaData.procedureColumnReturn
                        {
                            parameter.Direction = ParameterDirection.ReturnValue;
                        }

                        //get parameter precision and scale
                        parameter.SetParameterPrecisionAndScale(res);

                        parameter.SetParameterSize(res);
                        parameter.SetParameterIsNullable(res);

                        col.Add(parameter);
                    }
                }
                finally
                {
                    if (res != null)
                    {
                        res.close();
                    }
                }
            }
            catch (Exception e)
            {
                //supress
#if DEBUG
                Console.WriteLine("Exception catched at AbstractDBConnection.GetProcedureColumns() : {0}\n{1}\n{2}", e.GetType().FullName, e.Message, e.StackTrace);
#endif
            }
            return(col);
        }