При чтении из БД Oracle данных типа (Type) Decimal (Size=12, Scale=6) и присвоении данных переменной типа Decimal или ячейки в Excel и в DataGrid, визуализация значений без знака разделителя целой и дробной части. Например, 5.01 как 501
Среда разработки Visual Studio 2003, проект VB.Application, доступ к БД Oracle с использованием ADO.NET, драйвера ODBC, объектов Adapter и DataSet.
Краткое содержание:
Me.OdbcSelectCommand32.CommandText = "SELECT ASKP.SALDO_PERETOK.* FROM ASKP.SALDO_PERETOK" & s1
Me.OdbcSelectCommand32.CommandText = "SELECT OBJECT_ID, DAY, P_0030, P_0100, P_0130, P_0200, P_0230, P_0300, P" & _
"_0330, P_0400, P_0430, P_0500, P_0530, P_0600, P_0630, P_0700, P_0730, P_0800, P" & _
"_0830/1000, P_0900, P_0930, P_1000, P_1030, P_1100, P_1130/1000, P_1200, P_1230, P_1300, P" & _
"_1330, P_1400, P_1430, P_1500, P_1530, P_1600, P_1630/1000, P_1700, P_1730, P_1800, P" & _
"_1830/1000, P_1900, P_1930, P_2000, P_2030, P_2100, P_2130, P_2200, P_2230, P_2300, P" & _
"_2330, P_2400, FILE_DAY FROM ASKP.SALDO_PERETOK" & s1
Me.OdbcSelectCommand32.Connection = Me.OdbcConnection1
Me.OdbcDataAdapter32.SelectCommand = Me.OdbcSelectCommand32
Me.OdbcDataAdapter32.TableMappings.AddRange(New System.Data.Common.DataTableMapping() {New System.Data.Common.DataTableMapping("Table", "SALDO_PERETOK", New System.Data.Common.DataColumnMapping() {New System.Data.Common.DataColumnMapping("OBJECT_ID", "OBJECT_ID"), New System.Data.Common.DataColumnMapping("DAY", "DAY"), New System.Data.Common.DataColumnMapping("P_0030", "P_0030"), New
. . .
System.Data.Common.DataColumnMapping("P_2330", "P_2330"), New System.Data.Common.DataColumnMapping("P_2400", "P_2400"), New System.Data.Common.DataColumnMapping("FILE_DAY", "FILE_DAY")})})
OdbcDataAdapter32.Fill(DataSet11)
Dim oExcel As Excel.Application
Dim oBook As Excel.Workbook
Dim oSheet As Excel.Worksheet
Dim i As Int16, d(5) As Decimal
. . .
Вариации присвоения данных и применения функций преобразования данных приводят к одинаковому результату – отсутствию знака разделителя целой и дробной части
Здравствуйте, KVit, Вы писали:
KV>При чтении из БД Oracle данных типа (Type) Decimal (Size=12, Scale=6) и присвоении данных переменной типа Decimal или ячейки в Excel и в DataGrid, визуализация значений без знака разделителя целой и дробной части. Например, 5.01 как 501
Какое значение читается из базы и какое значение в ячейке на самом деле — может разделитель дробной части пустой? (правда я не знаю, так бывает вообще? )
KV>Краткое содержание:
Неплохо бы обрамлять текст программы тегами кода — читать понятнее.
Re[2]: Почему визуализация значений Decimal без знака раздел
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, KVit, Вы писали:
KV>>При чтении из БД Oracle данных типа (Type) Decimal (Size=12, Scale=6) и присвоении данных переменной типа Decimal или ячейки в Excel и в DataGrid, визуализация значений без знака разделителя целой и дробной части. Например, 5.01 как 501
A>Какое значение читается из базы и какое значение в ячейке на самом деле — может разделитель дробной части пустой? (правда я не знаю, так бывает вообще? )
KV>>Краткое содержание:
A>Неплохо бы обрамлять текст программы тегами кода — читать понятнее.
Разделитель дробной части в Настройка>Панель управления>Язык и стандарты>числа — точка
Re[3]: Почему визуализация значений Decimal без знака раздел
Здравствуйте, KVit, Вы писали:
KV> Разделитель дробной части в Настройка>Панель управления>Язык и стандарты>числа — точка
1. Попробуй писать число 5.01.
2. Посмотри какой тип у ячейки, куда пишешь
3. напиши тестовый пример, где писалось бы фиксированное число в определенную ячейку в новый лист
У меня все работает на ура, все точки есть. Проверь, может у тебя Excel так глючит хитро?
Re[4]: Почему визуализация значений Decimal без знака раздел
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, KVit, Вы писали:
KV>> Разделитель дробной части в Настройка>Панель управления>Язык и стандарты>числа — точка
A>1. Попробуй писать число 5.01. A>2. Посмотри какой тип у ячейки, куда пишешь A>3. напиши тестовый пример, где писалось бы фиксированное число в определенную ячейку в новый лист
A>У меня все работает на ура, все точки есть. Проверь, может у тебя Excel так глючит хитро?
Проблема не в Excel. В DataGrid и в других объектах визуализации значений программы так же будет 501
//Если проверить Ваши догадки и добавить следующий код:
d(5) = 5.01
oSheet.Cells(2, 54).Value = d(5)
//то и получим в ячейке 5.01
//Я сформулирую свою проблему по-другому – «Почему в DataSet из Oracl посредством метода Adapter.Fill(DataSet) значение типа Decimal попадает без знака разделителя целой и дробной части?»
Если SQL Explorer отображает, что в таблице Oracl 5.01, а в таблице DataSet строка 501
//Если добавить код:
Здравствуйте, KVit, Вы писали:
KV>//Я сформулирую свою проблему по-другому – «Почему в DataSet из Oracl посредством метода Adapter.Fill(DataSet) значение типа Decimal попадает без знака разделителя целой и дробной части?»
Один исключен — Excel. Ура.
Идем дальше — по пути выкидывания DataAdapter и DataTable. Сделай просто DataReader и посмотри что он возвращает. Метод GetValue если не ошибаюсь. Посмотри заодно и на GetFieldType — что вернет.
Re[6]: Почему визуализация значений Decimal без знака раздел
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, KVit, Вы писали:
KV>>//Я сформулирую свою проблему по-другому – «Почему в DataSet из Oracl посредством метода Adapter.Fill(DataSet) значение типа Decimal попадает без знака разделителя целой и дробной части?»
A>Один исключен — Excel. Ура.
A>Идем дальше — по пути выкидывания DataAdapter и DataTable. Сделай просто DataReader и посмотри что он возвращает. Метод GetValue если не ошибаюсь. Посмотри заодно и на GetFieldType — что вернет.
//Прилагаю вырезку кода формирования DataTable
Public Class SALDO_PERETOKDataTable
Public Overloads Function AddSALDO_PERETOKRow( _
ByVal OBJECT_ID As Integer, _
ByVal DAY As Date, _
ByVal P_0030 As Decimal, _
ByVal P_0100 As Decimal, _
. . .
ByVal P_2400 As Decimal, _
ByVal FILE_DAY As Date) As SALDO_PERETOKRow
Me.Rows.Add(rowSALDO_PERETOKRow)
Return rowSALDO_PERETOKRow
End Function
End Class
Public Class SALDO_PERETOKRow
Private tableSALDO_PERETOK As SALDO_PERETOKDataTable
Friend Sub New(ByVal rb As DataRowBuilder)
MyBase.New(rb)
Me.tableSALDO_PERETOK = CType(Me.Table,SALDO_PERETOKDataTable)
End Sub
Public Property P_0030 As Decimal
Get
Try
Return CType(Me(Me.tableSALDO_PERETOK.P_0030Column),Decimal)
Catch e As InvalidCastException
Throw New StrongTypingException("Cannot get value because it is DBNull.", e)
End Try
End Get
Set
Me(Me.tableSALDO_PERETOK.P_0030Column) = value
End Set
End Property
End Class
//Выдаю схему таблицы DataSet в виде Schema.xml, а данные таблицы DataSet в виде Doc.xml
Dim filename As String = "D:\NetProject\Doc.xml"Dim fileSchema As String = "D:\NetProject\Schema.xml"
//Создайте FileStream, чтобы писать
Dim myFileStream As New System.IO.FileStream _
(filename, System.IO.FileMode.Create)
//Создём объект FileStream с именем файла
Dim SchemaStream As New System.IO.FileStream(fileSchema, System.IO.FileMode.Create)
//Пишем схему в файл.
DataSet11.WriteXmlSchema(SchemaStream)
//Закроем FileStream.
SchemaStream.Close()
//Создаём XmlTextWriter с fileStream.
Dim myXmlWriter As New System.Xml.XmlTextWriter _
(myFileStream, System.Text.Encoding.Unicode)
//Пишем в файл методом WriteXml.
DataSet11.WriteXml(myXmlWriter)
myXmlWriter.Close()
//Фрагмент схемы Schema.xml
<?xml version="1.0" ?>
- <xs:schema id="DataSet1" targetNamespace="http://www.tempuri.org/DataSet1.xsd" xmlns:mstns="http://www.tempuri.org/DataSet1.xsd" xmlns="http://www.tempuri.org/DataSet1.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
- <xs:element name="DataSet1" msdata:IsDataSet="true" msdata:CaseSensitive="true" msdata:Locale="ru-RU">
- <xs:complexType>
- <xs:choice maxOccurs="unbounded">
- <xs:element name="SALDO_PERETOK">
- <xs:complexType>
- <xs:sequence>
<xs:element name="OBJECT_ID"type="xs:int" />
<xs:element name="DAY"type="xs:dateTime" minOccurs="0" />
<xs:element name="P_0030"type="xs:decimal" minOccurs="0" />
<xs:element name="P_0100"type="xs:decimal" minOccurs="0" />
. . .
<xs:element name="P_2330"type="xs:decimal" minOccurs="0" />
<xs:element name="P_2400"type="xs:decimal" minOccurs="0" />
<xs:element name="FILE_DAY"type="xs:dateTime" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
//Фрагмент данных Doc.xml, где в колонках Р_.... Decimal попадает без знака разделителя целой и дробной, т.е. должны быть числа 5.549 5.338 5.255 и т.д.
- <DataSet1 xmlns="http://www.tempuri.org/DataSet1.xsd">
- <SALDO_PERETOK>
<OBJECT_ID>859</OBJECT_ID>
<DAY>2004-11-20T00:00:00.0000000+03:00</DAY>
<P_0030>5549</P_0030>
<P_0100>5338</P_0100>
<P_0130>5255</P_0130>
<P_0200>5121</P_0200>
<P_0230>5081</P_0230>
. . .
<P_2300>5912</P_2300>
<P_2330>5116</P_2330>
<P_2400>4463</P_2400>
<FILE_DAY>2004-11-25T11:34:02.0000000+03:00</FILE_DAY>
</SALDO_PERETOK>
</DataSet1>
//Я в затруднении, что можно предпринять?
Re[7]: Почему визуализация значений Decimal без знака раздел
Здравствуйте, KVit, Вы писали:
KV>//Я в затруднении, что можно предпринять?
А я в затруднении что-либо понять. Горы кода, какие-то файлы... Возьми новый проект, засунь туда connection, command (типа select * from ТВОЯТАБЛИЦА), открой коннект и сделай ExecuteReader.
Это займет 20 мин, а ситуацию прояснит:
— если вернется 5012, значит глюки в базе
— если вернется 5.012, значит глюки в коде
Re[8]: Почему визуализация значений Decimal без знака раздел
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, KVit, Вы писали:
KV>>//Я в затруднении, что можно предпринять?
A>А я в затруднении что-либо понять. Горы кода, какие-то файлы... Возьми новый проект, засунь туда connection, command (типа select * from ТВОЯТАБЛИЦА), открой коннект и сделай ExecuteReader.
A>Это займет 20 мин, а ситуацию прояснит:
A>- если вернется 5012, значит глюки в базе A>- если вернется 5.012, значит глюки в коде
//Я последовал Вашим рекомендациям:
Dim dreader As System.Data.Odbc.OdbcDataReader
OdbcConnection1.Open()
dreader = OdbcSelectCommand32.ExecuteReader()
If dreader.Read() Then
s1 = " GetValue=" & dreader.GetValue(2).ToString()
s = dreader("P_0030").GetType.ToString()
End If
lblSQL.Text = s1 & " GetType P_0030=" & s
dreader.Close()
OdbcConnection1.Close()
//Получил то, что и ожидал
GetValue=5549 GetType P_0030=System.Decimal
//На базу грешить не могу, т.к. я уже писал, что после Select в SQL Explorer BDE данные типа Decimal получаю как положено.
Если у Вас появятся мысли что ещё можно предпринять, то буду благодарен.
Re[9]: Почему визуализация значений Decimal без знака раздел
Здравствуйте, KVit, Вы писали:
KV> GetValue=5549 GetType P_0030=System.Decimal
KV>//На базу грешить не могу, т.к. я уже писал, что после Select в SQL Explorer BDE данные типа Decimal получаю как положено. KV>Если у Вас появятся мысли что ещё можно предпринять, то буду благодарен.
А придется погрешить на базу — больше не на кого.
Итак, ищем в базе. Надо создать новую хранимую процедуру без параметров, которая возвращает одну строку с decimal. Это будет что-то похожее на
select 1.2345 as res
и повторить предыдущий код на нем.
Если выдаст 1.2345, надо искать что не так было в исходном запросе.
Если выдаст 12345, значит ODBC+Oracle+.NET имеющихся у тебя версий — в принципе неработоспособная связка.
Кстати, а зачем собтсвенно odbc? В .NET есть же есть родные компоненты для работы с Oracle.
Re[10]: Почему визуализация значений Decimal без знака разде
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, KVit, Вы писали:
KV>> GetValue=5549 GetType P_0030=System.Decimal
KV>>//На базу грешить не могу, т.к. я уже писал, что после Select в SQL Explorer BDE данные типа Decimal получаю как положено. KV>>Если у Вас появятся мысли что ещё можно предпринять, то буду благодарен.
A>А придется погрешить на базу — больше не на кого.
A>Итак, ищем в базе. Надо создать новую хранимую процедуру без параметров, которая возвращает одну строку с decimal. Это будет что-то похожее на A>
A>select 1.2345 as res
A>
A>и повторить предыдущий код на нем.
A>Если выдаст 1.2345, надо искать что не так было в исходном запросе. A>Если выдаст 12345, значит ODBC+Oracle+.NET имеющихся у тебя версий — в принципе неработоспособная связка.
A>Кстати, а зачем собтсвенно odbc? В .NET есть же есть родные компоненты для работы с Oracle.
//Я воспользовался советом – «искать в исходном запросе». Изменив запрос на :
Me.OdbcSelectCommand32.CommandText = "SELECT TO_CHAR(P_0030), TO_CHAR(P_0100 ,'9.999'), TO_NUMBER(P_0130) FROM ASKP.SALDO_PERETOK Where OBJECT_ID=859 And DAY=TO_DATE('20.11.2004','dd.mm.yyyy')"
//Преобразовывая Decimal в запросе в строку, получаем значение с разделителем целой и дробной частей в виде запятой или точки.
//Преобразовывая Decimal(строку) в запросе в число, получаем значение так же с разделителем, но число типа Double.
//Изменив таким образом запросы получаем приемлемый результат.
Огорчает, что текст запросов будет очень длинный и по-прежнему мне не ясно, почему Decimal получаем без разделителя целой и дробной частей.
Что скажите?
Re[11]: Почему визуализация значений Decimal без знака разде
Скажу то, что я работал ни с odbc, ни с oracle. А здесь похоже начинаются тонкости типа установить какую-то галочку или прописать что-то... Выливается это в то, что строка передается, а с decimal какие-то замороки.
Попробуй второй путь — через хранимую процедуру. Кстати, почему ты не используешь ХП?
Re[12]: Почему визуализация значений Decimal без знака разде
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, KVit, Вы писали:
KV>>Что скажите?
A>Скажу то, что я работал ни с odbc, ни с oracle. А здесь похоже начинаются тонкости типа установить какую-то галочку или прописать что-то... Выливается это в то, что строка передается, а с decimal какие-то замороки.
A>Попробуй второй путь — через хранимую процедуру. Кстати, почему ты не используешь ХП?
Передаётся правильно не только строка, но и Double.
Для работы с Oracle в нашей фирме принято писать COM объекты – классы в основном на Delphi, которые располагают на сервере приложений. Пользовательские приложения обращаются к этим классам через DCOM. Поэтому на пользовательских местах клиенты Oracle отсутствуют и хранимые процедуры не популярны, т.е. я их не использовал, но можно попробовать.
С ODBC мне комфортнее работать, драйверы к БД можно использовать родные и Microsoft, alias БД можно использовать компонентами Delphi и Visual Studio.
Я доволен, что Вы уделили мне внимание ведь две головы лучше, чем одна.
Если у Вас возникнет новый путь поиска решения проблемы, то буду рад продолжить.
Re[13]: Почему визуализация значений Decimal без знака разде
Здравствуйте, KVit, Вы писали:
KV>Передаётся правильно не только строка, но и Double.
Из запроса или в запрос? Вроде из запроса decimal не хотел возвращаться.
KV>Для работы с Oracle в нашей фирме принято писать COM объекты – классы в основном на Delphi, которые располагают на сервере приложений. Пользовательские приложения обращаются к этим классам через DCOM. Поэтому на пользовательских местах клиенты Oracle отсутствуют и хранимые процедуры не популярны
Почему поэтому? Не вижу связи. С пользовательского места по DCOM-у просто вызывают клиента oracle на сервере приложений. Этот вызов не требует "не использовать ХП". Или я чего-то не понял?
KV>С ODBC мне комфортнее работать, драйверы к БД можно использовать родные и Microsoft, alias БД можно использовать компонентами Delphi и Visual Studio.
Ясно. Это немного не в тему, а ты сравнивал скорость работы:
— odbc родной
— odbc MS
— .NET
Интересно для общего развития.
KV> Я доволен, что Вы уделили мне внимание ведь две головы лучше, чем одна. KV>Если у Вас возникнет новый путь поиска решения проблемы, то буду рад продолжить.
Попробуй различные варианты:
1. Простая ХП типа "select 1.2345 as res" + родной адаптер .NET
2. ХП + odbc
3. запрос "select 1.2345 as res" + родной адаптер .NET
4. запрос + odbc
Re[14]: Почему визуализация значений Decimal без знака разде
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, KVit, Вы писали:
KV>>Передаётся правильно не только строка, но и Double.
A>Из запроса или в запрос? Вроде из запроса decimal не хотел возвращаться.
KV>>Для работы с Oracle в нашей фирме принято писать COM объекты – классы в основном на Delphi, которые располагают на сервере приложений. Пользовательские приложения обращаются к этим классам через DCOM. Поэтому на пользовательских местах клиенты Oracle отсутствуют и хранимые процедуры не популярны
A>Почему поэтому? Не вижу связи. С пользовательского места по DCOM-у просто вызывают клиента oracle на сервере приложений. Этот вызов не требует "не использовать ХП". Или я чего-то не понял?
KV>>С ODBC мне комфортнее работать, драйверы к БД можно использовать родные и Microsoft, alias БД можно использовать компонентами Delphi и Visual Studio.
A>Ясно. Это немного не в тему, а ты сравнивал скорость работы: A>- odbc родной A>- odbc MS A>- .NET A>Интересно для общего развития.
KV>> Я доволен, что Вы уделили мне внимание ведь две головы лучше, чем одна. KV>>Если у Вас возникнет новый путь поиска решения проблемы, то буду рад продолжить.
A>Попробуй различные варианты:
A>1. Простая ХП типа "select 1.2345 as res" + родной адаптер .NET A>2. ХП + odbc A>3. запрос "select 1.2345 as res" + родной адаптер .NET A>4. запрос + odbc
Если в запросе decimal преобразуется средствами Oracle в строку SQL функцией TO_CHAR(decimal-колонка) или в Double SQL функцией TO_NUMBER(decimal-колонка), то получаем разделитель, а если в SQL запросе просто decimal-колонка, то разделителя нет. Интересно, что SQL функция TO_NUMBER используется для преобразования «символьного» представления числа в «числовой» тип данных.
COM компонента может использовать ХП, я не пробовал использовать ХП и не понял зачем мне ХП "select 1.2345 as res".
Скорость работы драйверов не сравнивал ведь может повлиять работа сети, но возможно исследую.
Re[15]: Почему визуализация значений Decimal без знака разде
Здравствуйте, KVit, Вы писали:
KV>Если в запросе decimal преобразуется средствами Oracle в строку SQL функцией TO_CHAR(decimal-колонка) или в Double SQL функцией TO_NUMBER(decimal-колонка), то получаем разделитель, а если в SQL запросе просто decimal-колонка, то разделителя нет.
Ясно, так ведет себя odbcCommand. Надо проверить что будет делать OracleCommand. Если так же, значит это фича oracle. Если иначе, значит это несовместимость .NET с ODBC.
KV> Интересно, что SQL функция TO_NUMBER используется для преобразования «символьного» представления числа в «числовой» тип данных.
KV>COM компонента может использовать ХП, я не пробовал использовать ХП и не понял зачем мне ХП "select 1.2345 as res".
— Зачем ХП? Может лучше будет, кто знает?
— Зачем такой запрос? Для простоты. Это самый простой запрос, какой я смог придумать. С учетом вышесказанного еще неплохо проверить "select TO_NUMBER(1.2345) as res".
Re[16]: Почему визуализация значений Decimal без знака разде
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, KVit, Вы писали:
KV>>Если в запросе decimal преобразуется средствами Oracle в строку SQL функцией TO_CHAR(decimal-колонка) или в Double SQL функцией TO_NUMBER(decimal-колонка), то получаем разделитель, а если в SQL запросе просто decimal-колонка, то разделителя нет.
A>Ясно, так ведет себя odbcCommand. Надо проверить что будет делать OracleCommand. Если так же, значит это фича oracle. Если иначе, значит это несовместимость .NET с ODBC.
KV>> Интересно, что SQL функция TO_NUMBER используется для преобразования «символьного» представления числа в «числовой» тип данных.
A>
KV>>COM компонента может использовать ХП, я не пробовал использовать ХП и не понял зачем мне ХП "select 1.2345 as res".
A>- Зачем ХП? Может лучше будет, кто знает?
A>- Зачем такой запрос? Для простоты. Это самый простой запрос, какой я смог придумать. С учетом вышесказанного еще неплохо проверить "select TO_NUMBER(1.2345) as res".
Спасибо за советы.
Пока не получилось ими воспользоваться, т.к. у меня «insufficient privileges» недостаточные привилегии, чтобы создать OracleCommand и Create procedure.