Список форумов www.integro.ru www.integro.ru
ЦСИ ИНТЕГРО
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Чтение из справочника поля длиной больше 32k символов, возможно ?

 
Начать новую тему   Ответить на тему    Список форумов www.integro.ru -> Вопросы разработчиков
Предыдущая тема :: Следующая тема  
Автор Сообщение
Вольхин Коля



Зарегистрирован: 13.06.2013
Сообщения: 11
Откуда: Россия

СообщениеДобавлено: Вс 11 Авг 2013 18:51    Заголовок сообщения: Чтение из справочника поля длиной больше 32k символов, возможно ? Ответить с цитатой

Чтение из справочника поля длиной больше 32k символов, возможно ?

задача : сохранять и загружать настройки карты

решение : генерить xml с настройками , сохранять в файл или БД.

с файлом ни каких проблем.

xml любого размера в БД сохраняется без проблем.

но при чтении проблема в том что у IIngeoSemDbValue поле Value хотя и объявлено как безразмерный object Value , но реально в Value больше чем 32k символов не помещается , как остальные символы прочитать ?

при этом в справочнике для "Строка" больше 8000 не задать. для "Документа" / "Текста" конечно можно указать 2 147 483 647 но больше 32768 прочитать низя :(

в TODO себе добавьте "не позволять указывать длину поля больше 32768" .

или средствами InGeo можно больше читать ?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Михаил Власов



Зарегистрирован: 14.02.2005
Сообщения: 580
Откуда: ИНТЕГРО

СообщениеДобавлено: Пн 12 Авг 2013 10:51    Заголовок сообщения: Ответить с цитатой

Создан справочник "test_memo" с двумя полями "Code" целого типа и "Data" тип Текст.

Вручную добавлена одна запись с "Code"=1 и "Data"=<null>.

В тестовом модуле созданы две процедуры для обновления и считывания:
Код:
sub test_update_memo
   dim i, s
   s = ""
   for i = 0 to 30000
      s = s & CStr(i) & vbNewLine
   next
   
   ActiveDb.SemDbTables("test_memo").UpdateData "Data=?", "Code=1", Array(s)
end sub



sub test_select_memo
   dim aQuery
   set aQuery = ActiveDb.SemDbTables("test_memo").SelectData("Data", "Code=1")
   if not aQuery.EOF then
      dim aValue
      aValue = aQuery("Data")
      MsgBox Len(aValue)
   end if
end sub


На ИнГео 4.6 (релиз-кандидат) проверено на MSSQL, SQLite, Paradox - 200K сохраняется и считывается.[/url]

_________________
С уважением, Михаил Власов.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Вольхин Коля



Зарегистрирован: 13.06.2013
Сообщения: 11
Откуда: Россия

СообщениеДобавлено: Пн 12 Авг 2013 11:19    Заголовок сообщения: Ответить с цитатой

я пишу под 4.4 , может быть в этом дело

ЗЫ
запущу у себя ваш скрипт. отпишусь
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Вольхин Коля



Зарегистрирован: 13.06.2013
Сообщения: 11
Откуда: Россия

СообщениеДобавлено: Пн 12 Авг 2013 13:26    Заголовок сообщения: Ответить с цитатой

проверил

Код:
rem--

   dim iX, sX
   sX = ""
   for iX = 0 to 40000
      sX = sX & CStr(iX) & vbNewLine
   next

   ActiveDb.SemDbTables("test_memo").UpdateData "Data=?", "Code=1", Array(sX)

   dim aQueryX
   set aQueryX = ActiveDb.SemDbTables("test_memo").SelectData("Data", "Code=1")
   if not aQueryX.EOF then
      dim aValueX
      aValueX = aQueryX("Data")
      MsgBox Len(aValueX)
   end if

rem--


из БД строчку сохранил в файл , конец файла :
"
1307
1308
1309
131
"
размер файла 6 755 байт
в БД у поля Data размер 2 147 483 647

если в строке "for iX = 0 to 40000" задать 50000 , то SQL начинает ругаться, просит строчку усечь справа. лажа с этим вашим VB скриптом , даже 32к записать в БД не может )

на шарпе код такой :

Код:

TextEncoding.GetString(
(byte[]) GetRefBookDataByCurrentRow
                                                (
                                                    MapViewSettingsRefBook
                                                    , C_FieldSettingName
                                                    , C_FieldCodeName
                                                    , MapViewSettingsDataGridView
                                                    , C_ColumnCodeName
                                                ).Fields[C_FirstIndex].Value
)


Код:

        private static IIngeoSemDbDataSet GetRefBookDataByCurrentRow
            (
            IIngeoRefBook refBookObject
            , string selectFieldName
            , string keyFieldName
            , DataGridView mapViewSettingsDataGridView
            , string keyColumnName
            )
        {
            return refBookObject.SemDbTable.SelectData
                (
                    selectFieldName
                    , string.Format
                          (
                              "{0}='{1}'"
                              , keyFieldName
                              , GetCurrentRowCellStringValue(mapViewSettingsDataGridView, keyColumnName)
                          )
                );
        }


спишем не то что 4.4 не умеет больше 32к байт прочитать

ЗЫ
на 3 000 000 повисло , на 90 000 тоже зависло на долго, мне терпежа не хватало дождаться пока развиснется.



test_memo_vb_script.png
 Описание:
 Размер файла:  246.82 KB
 Просмотрено:  15230 раз(а)

test_memo_vb_script.png




Последний раз редактировалось: Вольхин Коля (Пн 12 Авг 2013 15:15), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Вольхин Коля



Зарегистрирован: 13.06.2013
Сообщения: 11
Откуда: Россия

СообщениеДобавлено: Пн 12 Авг 2013 13:42    Заголовок сообщения: Ответить с цитатой

ещё весёлый глюк со знаком "?" который при запросе к базе заменяется на значение параметра., даже если параметр не задан.

я в БД пишу xml :
<?xml version="1.0" encoding="UTF-16" ?>

первый символ "?" ингео игнорирует, а на второй реагирует : меняет его на ":PARAM0" , поскольку я в базу писал блоб а не текст , то я эту подмену сразу не заметил , думал у меня xml не правильный

пришлось к прочитанному из базы значению применять .Replace(C_Param0TrickString, C_Param0TrickSymbol)

в 4.6 уже исправлено ?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Михаил Власов



Зарегистрирован: 14.02.2005
Сообщения: 580
Откуда: ИНТЕГРО

СообщениеДобавлено: Пн 12 Авг 2013 14:03    Заголовок сообщения: Ответить с цитатой

Вольхин Коля писал(а):
ещё весёлый глюк со знаком "?" который при запросе к базе заменяется на значение параметра., даже если параметр не задан.

я в БД пишу xml :
<?xml version="1.0" encoding="UTF-16" ?>

первый символ "?" ингео игнорирует, а на второй реагирует : меняет его на ":PARAM0" , поскольку я в базу писал блоб а не текст , то я эту подмену сразу не заметил , думал у меня xml не правильный

пришлось к прочитанному из базы значению применять .Replace(C_Param0TrickString, C_Param0TrickSymbol)

в 4.6 уже исправлено ?


Это какая функция?
На какой СУБД?
Дайте полный код.

_________________
С уважением, Михаил Власов.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Вольхин Коля



Зарегистрирован: 13.06.2013
Сообщения: 11
Откуда: Россия

СообщениеДобавлено: Пн 12 Авг 2013 15:12    Заголовок сообщения: Ответить с цитатой

там "спагеттити код" устанете разбирать.

БД ( MS SQL 2008 R2 ) :

Microsoft SQL Server Management Studio 10.50.2550.0
Microsoft Analysis Services Client Tools 10.50.2500.0
Microsoft Data Access Components (MDAC) 6.1.7601.17514
Microsoft MSXML 3.0 4.0 5.0 6.0
Microsoft Internet Explorer 9.10.9200.16635
Microsoft .NET Framework 2.0.50727.5472
Operating System 6.1.7601

полный код .. много букв , разворачиваю в обратном порядке :


Код:
        /// <summary>
        /// Сохраняет Настройку просмотра карты в Бд
        /// <param name="mapViewSettingsDataGridView">Датагрид</param>
        /// <param name="gisApplication">ГИС приложение</param>
        /// <param name="textEncoding">Кодировка символов</param>
        /// <param name="mapViewSettingSaveFileDialog">Объект SaveFileDialog</param>
        /// <param name="mapViewSettingsRefBook">Объект справочника</param>
        /// </summary>
        private static void SaveMapViewSettingToDb
            (
            DataGridView mapViewSettingsDataGridView
            , IIngeoApplication gisApplication
            , Encoding textEncoding
            , SaveFileDialog mapViewSettingSaveFileDialog
            , IIngeoRefBook mapViewSettingsRefBook
            )
        {
            if (!IsDataGridViewRowSelected(mapViewSettingsDataGridView)) return;

            var updateWithValue = GetMapViewSettingsXml
                (
                    gisApplication
                    , textEncoding
                    , GetCurrentRowCellStringValue(mapViewSettingsDataGridView, C_ColumnSettingCaptionName)
                );


            if (updateWithValue.Length > C_MaxDbStringSize)
            {
                if (MessageBox.Show
                        (
                            Resource.WarnTextMapViewSettingSizeGreaterDbFieldSize
                            , Resource.WarnTitleMapViewSettingSizeGreaterDbFieldSize
                            , MessageBoxButtons.OKCancel
                            , MessageBoxIcon.Question
                        ) == DialogResult.OK
                    )
                    SaveMapViewSettings
                        (
                            gisApplication
                            , textEncoding
                            , mapViewSettingSaveFileDialog
                        );

                return;
            }

            if (UpdateRefBookByDataGridViewColumn
                (
                    mapViewSettingsDataGridView
                    , C_ColumnCodeName
                    , updateWithValue
                    , mapViewSettingsRefBook
                    , C_FieldCodeName
                    , C_FieldSettingName
                    , C_ColumnSettingCaptionName
                ))

// ReSharper disable PossibleNullReferenceException
                mapViewSettingsDataGridView.CurrentRow.Cells[C_ColumnIsSavedName].Value = true;
// ReSharper restore PossibleNullReferenceException
        }


генерим xml
Код:
        /// <summary>
        /// Возвращает настройки просмотра карты
        /// <param name="gisApplication">ГИС приложение</param>
        /// <param name="textEncoding">Кодировка строки настроек</param>
        /// <returns>Настройки просмотра</returns>
        /// </summary>
        //private static byte[] GetMapViewSettingsXml
        private static string GetMapViewSettingsXml
            (
            IIngeoApplication gisApplication
            , Encoding textEncoding
            , string mapViewSettingName = null
            )
        {
            var xmlStream = new MemoryStream();
            //var xmlStream = new StringWriter();
           
            var xmlWriter = XmlWriter.Create
                (
                    xmlStream
                    , new XmlWriterSettings
                        {
                            Encoding = textEncoding,
                            ConformanceLevel = ConformanceLevel.Document,
                            CloseOutput = true
                        }
                );

            xmlWriter.WriteStartDocument();

            //start C_MapViewSettingXmlRootTagName
            xmlWriter.WriteStartElement(C_MapViewSettingXmlRootTagName);
            if (string.IsNullOrEmpty(mapViewSettingName)) mapViewSettingName = C_NewSettingName;
            xmlWriter.WriteAttributeString(C_NameAttributeName, mapViewSettingName);

            //start Surface tag
            xmlWriter.WriteStartElement(C_SurfaceTagName);

            var surface = gisApplication.MainWindow.MapWindow.Surface;

            xmlWriter.WriteAttributeString(C_ZoomscaleAttributeName,
                                           surface.Projection.ZoomScale.ToString(CultureInfo.InvariantCulture));

            xmlWriter.WriteAttributeString(C_X1AttributeName, surface.PaperX1.ToString(CultureInfo.InvariantCulture));
            xmlWriter.WriteAttributeString(C_X2AttributeName, surface.PaperX2.ToString(CultureInfo.InvariantCulture));
            xmlWriter.WriteAttributeString(C_Y1AttributeName, surface.PaperY1.ToString(CultureInfo.InvariantCulture));
            xmlWriter.WriteAttributeString(C_Y2AttributeName, surface.PaperY2.ToString(CultureInfo.InvariantCulture));

            //finish Surface tag
            xmlWriter.WriteEndElement();
.. skip ..
            //start ActiveProject tag
            xmlWriter.WriteStartElement(C_ActiveProjectTagName);
            xmlWriter.WriteAttributeString(C_IdTag, gisApplication.ActiveProjectView.Project.ID);
            //finish ActiveProject tag
            xmlWriter.WriteEndElement();

            //End C_MapViewSettingXmlRootTagName
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Flush();

            xmlStream.Position = C_FirstIndex;
            return textEncoding.GetString(xmlStream.ToArray());
        }


Код:
        /// <summary>
        /// Обновляет справочник по ячейке датагрида
        /// <param name="refBookDataGridView">Датагрид</param>
        /// <param name="columnKeyName">Колонка с ключом</param>
        /// <param name="updateWithValue">Значение для обновления</param>
        /// <param name="mapViewSettingsRefBook">Объект справочника</param>
        /// <param name="fieldKeyName">Название поля ключа</param>
        /// <param name="updateWithFieldName">Имя поля для обновления</param>
        /// <param name="recordNameColumnName">Название записи</param>
        /// </summary>
        private static bool UpdateRefBookByDataGridViewColumn
            (
            DataGridView refBookDataGridView
            , string columnKeyName
            , string updateWithValue
            , IIngeoRefBook mapViewSettingsRefBook
            , string fieldKeyName
            , string updateWithFieldName
            , string recordNameColumnName
            )
        {
            if (refBookDataGridView.CurrentRow == null) return false;
            var setttingCaption = GetCurrentRowCellStringValue(refBookDataGridView, recordNameColumnName);
           
            int settingKeyValue;
            if (int.TryParse(
                //refBookDataGridView.CurrentRow.Cells[columnKeyName].Value.ToString()
                GetCurrentRowCellStringValue(refBookDataGridView, columnKeyName)
                , out settingKeyValue))
            {
                UpdateRefBookField
                    (
                        ref mapViewSettingsRefBook
                        , fieldKeyName
                        , settingKeyValue
                        , updateWithFieldName
                        , updateWithValue
                    );
                return true;
            }


            MessageBox.Show
                (
                    Resource.WarnMsgSaveMapViewSettingFail
                    + string.Format(" Код = '{0}' Название = '{1}'"
                                    , settingKeyValue, setttingCaption)
                );
            return false;
        }



Код:
        /// <summary>
        /// Обновить поле справочника
        /// <param name="refBookObject">Объект справочника</param>
        /// <param name="tableKeyFieldName">Имя поля ключа</param>
        /// <param name="tableKeyFieldValue">Значение ключа</param>
        /// <param name="tableFieldToUpdateName">Обновить поле</param>
        /// <param name="tableFieldToUpdateValue">Обновить поле значением</param>
        /// </summary>
        private static void UpdateRefBookField
            (
            ref IIngeoRefBook refBookObject
            , string tableKeyFieldName
            , int tableKeyFieldValue
            , string tableFieldToUpdateName
            , string tableFieldToUpdateValue
            )
        {
            refBookObject.SemDbTable.UpdateData
                (
                    //string.Format
                    //    (
                    //        "{0}='{1}'"
                    //        , tableFieldToUpdateName
                    //        , tableFieldToUpdateValue
                    //    )

                    GetFieldEQValue(tableFieldToUpdateName, tableFieldToUpdateValue)
                    , GetFieldEQValue(tableKeyFieldName, tableKeyFieldValue.ToString(CultureInfo.InvariantCulture))
                );
        }


Код:
        /// <summary>
        /// Получить строку формата Поле='Значение'
        /// <param name="tableKeyFieldName">Поле</param>
        /// <param name="tableKeyFieldValue">Значение</param>
        /// <returns></returns>
        /// </summary>
        private static string GetFieldEQValue(string tableKeyFieldName, string tableKeyFieldValue)
        {
            return string.Format
                (
                    "{0}='{1}'"
                    , tableKeyFieldName
                    , tableKeyFieldValue
                );
        }


как то так, полный код во вложении

ЗЫ
по поводу чтения из БД подсказывают , что это возможно настройками BDE Admin ограничен максимальный размер данных при чтении.



MapViewSettings.zip
 Описание:

Скачивание
 Название файла:  MapViewSettings.zip
 Размер файла:  57.1 KB
 Скачено:  891 раз(а)

Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Михаил Власов



Зарегистрирован: 14.02.2005
Сообщения: 580
Откуда: ИНТЕГРО

СообщениеДобавлено: Пн 12 Авг 2013 15:43    Заголовок сообщения: Ответить с цитатой

Попробуйте вместо:
Код:

   private static void UpdateRefBookField
            (
            ref IIngeoRefBook refBookObject
            , string tableKeyFieldName
            , int tableKeyFieldValue
            , string tableFieldToUpdateName
            , string tableFieldToUpdateValue
            )
        {
            refBookObject.SemDbTable.UpdateData
                (
                    //string.Format
                    //    (
                    //        "{0}='{1}'"
                    //        , tableFieldToUpdateName
                    //        , tableFieldToUpdateValue
                    //    )

                    GetFieldEQValue(tableFieldToUpdateName, tableFieldToUpdateValue)
                    , GetFieldEQValue(tableKeyFieldName, tableKeyFieldValue.ToString(CultureInfo.InvariantCulture))
                );
        }

сделать так:
Код:

   private static void UpdateRefBookField
            (
            ref IIngeoRefBook refBookObject
            , string tableKeyFieldName
            , int tableKeyFieldValue
            , string tableFieldToUpdateName
            , string tableFieldToUpdateValue
            )
        {
            refBookObject.SemDbTable.UpdateData
                (
                    tableFieldToUpdateName + "=?",
                    , GetFieldEQValue(tableKeyFieldName, tableKeyFieldValue.ToString(CultureInfo.InvariantCulture)),
 new object[] { tableFieldToUpdateValue }
                );
        }

_________________
С уважением, Михаил Власов.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Вольхин Коля



Зарегистрирован: 13.06.2013
Сообщения: 11
Откуда: Россия

СообщениеДобавлено: Пн 12 Авг 2013 23:47    Заголовок сообщения: Ответить с цитатой

да . конечно. это выход.

но лучше у себя багу с вставкой ":PARAM0" при отсутствии параметров поправьте :roll:
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Михаил Власов



Зарегистрирован: 14.02.2005
Сообщения: 580
Откуда: ИНТЕГРО

СообщениеДобавлено: Вт 13 Авг 2013 09:57    Заголовок сообщения: Ответить с цитатой

Вольхин Коля писал(а):
но лучше у себя багу с вставкой ":PARAM0" при отсутствии параметров поправьте Rolling Eyes


На 4.6 нормально обновляет.

Но лучше использовать параметризированное обновление. Могут ведь и символы апострофа в строке встретиться.

_________________
С уважением, Михаил Власов.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Вольхин Коля



Зарегистрирован: 13.06.2013
Сообщения: 11
Откуда: Россия

СообщениеДобавлено: Чт 17 Окт 2013 19:39    Заголовок сообщения: Ответить с цитатой

"Но лучше использовать параметризированное обновление."

да оно помогло. но не до конца потому что соединение через ODBC тоже не позволяет слишком много записать

пришлось резать на кусочки при записи и склеивать при чтении
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов www.integro.ru -> Вопросы разработчиков Часовой пояс: GMT + 5
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете добавлять приложения в этом форуме
Вы можете скачивать файлы в этом форуме


© phpBB Group
Русская поддержка phpBB