System.Data.Odbc.OdbcDataReader.OdbcDataReader.GetValue C# (CSharp) Метод

GetValue() публичный Метод

public GetValue ( int i ) : object
i int
Результат object
		object GetValue (int i)
		{
			if (IsClosed)
				throw new InvalidOperationException ("The reader is closed.");
			if (currentRow == -1)
				throw new InvalidOperationException ("No data available.");
			if (i > cols.Length-1 || i < 0)
				throw new IndexOutOfRangeException ();

			OdbcReturn ret;
			int outsize = 0, bufsize;
			byte[] buffer;
			OdbcColumn col = GetColumn (i);
			object DataValue = null;
			ushort ColIndex = Convert.ToUInt16 (i + 1);

			// Check cached values
			if (col.Value == null) {
				// odbc help file
				// mk:@MSITStore:C:\program%20files\Microsoft%20Data%20Access%20SDK\Docs\odbc.chm::/htm/odbcc_data_types.htm
				switch (col.OdbcType) {
				case OdbcType.Bit:
					short bit_data = 0;
					ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref bit_data, 0, ref outsize);
					if (outsize != (int) OdbcLengthIndicator.NullData)
						DataValue = bit_data == 0 ? "False" : "True";
					break;
				case OdbcType.Numeric:
				case OdbcType.Decimal:
					bufsize = 50;
					buffer = new byte [bufsize];  // According to sqlext.h, use SQL_CHAR for decimal.
					// FIXME : use Numeric.
					ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.CHAR, buffer, bufsize, ref outsize);
					if (outsize!=-1) {
						byte [] temp = new byte [outsize];
						for (int j = 0; j < outsize; j++)
							temp [j] = buffer [j];
						DataValue = Decimal.Parse (Encoding.Default.GetString (temp),
							CultureInfo.InvariantCulture);
					}
					break;
				case OdbcType.TinyInt:
					short short_data = 0;
					ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref short_data, 0, ref outsize);
					DataValue = Convert.ToByte (short_data);
					break;
				case OdbcType.Int:
					int int_data = 0;
					ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref int_data, 0, ref outsize);
					DataValue = int_data;
					break;

				case OdbcType.SmallInt:
					short sint_data = 0;
					ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref sint_data, 0, ref outsize);
					DataValue = sint_data;
					break;

				case OdbcType.BigInt:
					long long_data = 0;
					ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref long_data, 0, ref outsize);
					DataValue = long_data;
					break;
				case OdbcType.NChar:
					bufsize = 255;
					buffer = new byte [bufsize];
					ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.WCHAR, buffer, bufsize, ref outsize);
					if (outsize != (int) OdbcLengthIndicator.NullData)
						if (!(ret == OdbcReturn.SuccessWithInfo
						       && outsize == (int) OdbcLengthIndicator.NoTotal))
							DataValue = Encoding.Unicode.GetString (buffer, 0, outsize);
					break;
				case OdbcType.NText:
				case OdbcType.NVarChar:
					bufsize = (col.MaxLength < 127 ? (col.MaxLength*2+1) : 255);
					buffer = new byte[bufsize];  // According to sqlext.h, use SQL_CHAR for both char and varchar
					StringBuilder sb = new StringBuilder ();
					char[] charBuffer = new char[bufsize];
					Decoder unicodeDecoder = Encoding.Unicode.GetDecoder ();
					do {
						ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize);
						if (ret == OdbcReturn.Error)
							break;
						// Fix for strance ODBC drivers (like psqlODBC)
						if (ret == OdbcReturn.Success && outsize==-1)
							ret = OdbcReturn.NoData;

						if (ret == OdbcReturn.Success || ret == OdbcReturn.SuccessWithInfo) {
							if (outsize >= bufsize || outsize == (int)OdbcLengthIndicator.NoTotal)
								outsize = bufsize;
							int charCount = unicodeDecoder.GetChars (buffer, 0, outsize, charBuffer, 0);
							string strValue = new String (charBuffer, 0, charCount);
							sb.Append (RemoveTrailingNullChar (strValue));
						}
					} while (ret != OdbcReturn.NoData);
					DataValue = sb.ToString ();
					charBuffer = null;
					break;
				case OdbcType.Text:
				case OdbcType.VarChar:
					bufsize = (col.MaxLength < 255 ? (col.MaxLength+1) : 255);
					buffer = new byte[bufsize];  // According to sqlext.h, use SQL_CHAR for both char and varchar
					StringBuilder sb1 = new StringBuilder ();
					charBuffer = new char[bufsize];
					Decoder defaultDecoder = Encoding.Default.GetDecoder();
					do { 
						ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref outsize);
						if (ret == OdbcReturn.Error)
							break;
						// Fix for strance ODBC drivers (like psqlODBC)
						if (ret == OdbcReturn.Success && outsize==-1)
							ret = OdbcReturn.NoData;
						if (ret == OdbcReturn.Success || ret == OdbcReturn.SuccessWithInfo) {
							if (outsize >= bufsize || outsize == (int)OdbcLengthIndicator.NoTotal)
								outsize = bufsize - 1;
							int charCount = defaultDecoder.GetChars(buffer, 0, outsize, charBuffer, 0);
							sb1.Append(charBuffer, 0, charCount);
						}
					} while (ret != OdbcReturn.NoData);
					DataValue = sb1.ToString ();
					break;
				case OdbcType.Real:
					float float_data = 0;
					ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref float_data, 0, ref outsize);
					DataValue = float_data;
					break;
				case OdbcType.Double:
					double double_data = 0;
					ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref double_data, 0, ref outsize);
					DataValue = double_data;
					break;
				case OdbcType.Timestamp:
				case OdbcType.DateTime:
				case OdbcType.Date:
				case OdbcType.Time:
					OdbcTimestamp ts_data = new OdbcTimestamp();
					ret = libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, ref ts_data, 0, ref outsize);
					if (outsize != -1) {// This means SQL_NULL_DATA
						if (col.OdbcType == OdbcType.Time) {
							// libodbc returns value in first three fields for OdbcType.Time 
							DataValue = new System.TimeSpan (ts_data.year, ts_data.month, ts_data.day);
						} else {
							DataValue = new DateTime(ts_data.year, ts_data.month,
							                         ts_data.day, ts_data.hour, ts_data.minute,
							                         ts_data.second);
							if (ts_data.fraction != 0)
								DataValue = ((DateTime) DataValue).AddTicks ((long)ts_data.fraction / 100);
						}
					}
					break;
				case OdbcType.VarBinary :
				case OdbcType.Image :
					bufsize = (col.MaxLength < 255 && col.MaxLength > 0 ? col.MaxLength : 255);
					buffer= new byte [bufsize];
					ArrayList al = new ArrayList ();
					//get the size of data to be returned.
					ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.BINARY, buffer, 0, ref outsize);
					if (outsize != (int) OdbcLengthIndicator.NullData) {
						do {
							ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.BINARY, buffer, bufsize, ref outsize);
							if (ret == OdbcReturn.Error)
								break;
							if (ret != OdbcReturn.NoData && outsize != -1) {
								if (outsize < bufsize) {
									byte [] tmparr = new byte [outsize];
									Array.Copy (buffer, 0, tmparr, 0, outsize);
									al.AddRange (tmparr);
								} else
									al.AddRange (buffer);
							} else {
								break;
							}
						} while (ret != OdbcReturn.NoData);
					}
					DataValue = al.ToArray (typeof (byte));
					break;
				case OdbcType.Binary :
					bufsize = col.MaxLength;
					buffer = new byte [bufsize];
					long read = GetBytes (i, 0, buffer, 0, bufsize);
					ret = OdbcReturn.Success;
					DataValue = buffer;
					break;
				default:
					bufsize = 255;
					buffer = new byte[bufsize];
					ret = libodbc.SQLGetData (hstmt, ColIndex, SQL_C_TYPE.CHAR, buffer, bufsize, ref outsize);
					if (outsize != (int) OdbcLengthIndicator.NullData)
						if (! (ret == OdbcReturn.SuccessWithInfo
						       && outsize == (int) OdbcLengthIndicator.NoTotal))
							DataValue = Encoding.Default.GetString (buffer, 0, outsize);
					break;
				}

				if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo) && (ret!=OdbcReturn.NoData))
					throw Connection.CreateOdbcException (OdbcHandleType.Stmt, hstmt);

				if (outsize == -1) // This means SQL_NULL_DATA 
					col.Value = DBNull.Value;
				else
					col.Value = DataValue;
			}
			return col.Value;
		}