Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Сокровищница
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  16:34[Войти] | [Зарегистрироваться]

Обсуждение материала
TMySQL - компонент для доступа к MySQL
Полный текст материала


Другие публикации автора: Дмитрий Ларионов

Цитата или краткий комментарий:

«... TMySQL - компонент для доступа к MySQL ...»


Важно:
  • Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
  • Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
  • При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
  • Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.



Добавить свое мнение.

Результаты голосования
Оценка содержания

  Содержит полезные и(или) интересные сведения
[1]29100%
 
  Ничего особенно нового и интересного
[2]00%
 
  Написано неверно (обязательно укажите почему)
[3]00%
 
Всего проголосовали: 29

Оценка стиля изложения

  Все понятно, материал читается легко
[1]27100%
 
  Есть неясности в изложении
[2]00%
 
  Непонятно написано, трудно читается
[3]00%
 
Всего проголосовали: 27




Смотрите также материалы по темам:
[mySQL]

Комментарии жителей
Отслеживать это обсуждение

Всего сообщений: 165

17-08-2013 08:12
На localhost все ок а по сети не могу приконектиться. Что это может быть? Фаервол отключен. Антивируса нет
может кому пригодится - в настройках сервера mysql нужно убрать параметр —skip-networking либо закоментировать


04-08-2011 14:38
Дмитрий, я давно пользуюсь Вашим классом, очень им доволен. Спасибо Вам за него!
Решил вынести код в отдельный design-time пакет. Но столкнулся с проблемой.

Для примера:
Имеем модуль компонента-наследника TEdit:

unit MyEdit;

interface
uses
  StdCtrls,
  Classes,
  SysUtils;

type
  TMyEdit=class(TEdit)
    private
      FFlag: boolean;
    published
      property Flag:boolean Read FFlag Write FFlag;
  end;

procedure Register;

implementation

uses MySQLClasses;

procedure Register;
begin
  RegisterComponents('My',[TMyEdit]);
end;

end.



Помещаем этот модуль в отдельный пакет.
В этот же пакет в секцию Contains помещаем MySQL.pas и MySQLClasses.pas.
Компилируем - Всё Ок.
Нажимаем Install - падает ошибка "Can't load package. Неверная попытка доступа к памяти".
Убираем MySQLClasses, оставляя MySQL - всё Ок.

Где косяк?


31-07-2011 23:12
Большое спасибо!


18-07-2011 06:58
Сначала испугался "красной строчки" - шестая делфя отказалась распознать тип TFormatSettings, однако, чуток потыкавшись в гугле
http://delphi.about.com/library/rtl/blrtlTFormatSettings.htm
нашел его определение и всё заработало.

Добрую неделю искал в гугле ответ на гласный, разбавленный ненормативной лексикой вопрос "как" и это первая ссылка, на которой нашелся актуальный материал. В общем, спасибо.

п.с. да, я знаю, что я некропостер
Сообщение не подписано


06-04-2011 10:18
сообщение от автора материала
Скажите, а возможно в принципе изменить api интерфейс для работы через http-туннель?
Имеется ввиду сама mysql не имеет внешнего выхода, а на сервере лежит скрипт который общается с mysql, а библиотека бы общалась бы с этим скриптом? К сожалению такого функционала не писал и не интересовался наличием сторонних решений по причине ненадобности.
Во-первых наверняка решения должны быть, поэтому традиционный посыл в гугл :) "mysql http туннель" наверняка даст результаты.
Во-вторых собственный "туннель" написать дело ну ни такое уж и сложное, дня наверно хватит. Скорей всего тебе достаточно функций принять/послать данные. Indy компоненты; банальные post запросы на запрос/отправку данных; авторизация через куки; подумать в каком виде удобнее работать с данными (json, xml, cvs, ...). Практически и всё.
 riff


06-04-2011 07:22
Здравствуйте.
Очень полезные компоненты. Автору мегареспект.
Скажите, а возможно в принципе изменить api интерфейс для работы через http-туннель? На сколько я знаю, хостеры часто дают доступ только так или по ssh


07-02-2011 04:47
сообщение от автора материала
а это так важно?
просто подсказать нельзя?

Ну ё-моё, чуть что хватаются за нож и готовы биться с невидимым врагом до последнего.

Я лишь спросил: "как в сообщении от такого-то числа сделать не получается?". Не буду же я его и 5-10 последующих переписывать.
Посмотрите, пожалуйста, его и последующие.
 riff


06-02-2011 00:33
непонял
у меня дата сообщения 03-02-2011 11:34
а это так важно?
просто подсказать нельзя?


04-02-2011 13:22
сообщение от автора материала
никак не могу разобраться как передавать данные в блоб поле!
Так "30-01-2008 01:36" не получается?
 riff


03-02-2011 11:34
Здравствуйте!
никак не могу разобраться как передавать данные в блоб поле!

есть переменная с изображением:
jpg :TJpegImage;

запрос должен быть такого типа:
MySQL.ExecSQL('INSERT INTO basa (pole1,pole2) VALUES ('test', КАРТИНКА)')

я вот не пойму как сделать чтобы вместо КАРТИНКА был jpg

Спасибо!





14-01-2011 13:15
to flai:
Пожалуй, хватит уже, а? Данная тема — обсуждение конкретной статьи. Все остальное — оффтоп. Поиск исполнителя для работы — злостный оффтоп. Есть городская площадь. Есть, в конце концов, СЛС или электронная почта. Только не злоупотребляйте и не будьте слишком навязчивым.
 Geo


13-01-2011 10:34
сообщение от автора материала
Я с MySql знаком не по наслышке а вот с Делфи увы второй рас всего сталкиваюсь.
Хм. Ну ты смотри, на мой демо как на икону не полагайся, там моск работал на холостых оборотах. Я туда кода понапихал только чтобы показать как и что можно вызывать...

Можно ли сделать редактирование данных во второй таблице? И именно редактировать данные которые загружаются после выбора категории.
Для редактирования существуют различные grid'ы, можно вызывать дополнительные диалоговые окна с полями ввода. Как в ListView комфортно редактировать я не знаю, там стандартно поле для ввода появляется только в первой колонке.

Как на php сделать знаю, а не делфи нет.
Ну по большому счёту так же. Ты либо по окончании редактирования какой-то строки формируешь sql команду (insert, update, delete) и выполняешь его MySql.ExecSql(), либо, например, с помощью компонент Indy отправляешь на сервер стандартный вебовский POST (ключ=значение&ключ=значение...), а на сервере его скриптами обрабатываешь, незабывая, кстати, блюсти секьюрность (куки, права доступа, и т.д.).
 riff


13-01-2011 10:11
Кто может данный скрипт переписать под конкретное задание?
О размере вознаграждения договоримся!
Пишите мне на мыло.


13-01-2011 07:45
Большое спасибо за помощь!
Я с MySql знаком не по наслышке а вот с Делфи увы второй рас всего сталкиваюсь.
А можно еще один вопрос?
Можно ли сделать редактирование данных во второй таблице? И именно редактировать данные которые загружаются после выбора категории. Как на php сделать знаю, а не делфи нет.
Заранее спасибо!


13-01-2011 02:22
сообщение от автора материала
Твой вопрос не связан с MySql, поэтому если будут и дальше возникать посторонние проблемы, то лучше направлять их на "круглый стол".

    ListItem := lvGroups.Items.Add;
    ListItem.Caption := Str; //Присваеваешь сначала строку Str
    ListItem.Caption := Str1; //а за тем тут же Str1


Ну и что должен после этого показывать ListView?

Текст в дополнительные колонки ListView добавляется следующим образом:

ListItem := ListView.Items.Add;
ListItem.Caption := 'aaa';
ListItem.SubItems.Add('bbb'); //колонка 2
ListItem.SubItems.Add('ccc'); //колонка3

 riff


12-01-2011 10:51
Помогите ночевку! пытаюсь сделать к группе описание, исправил ваш пример.

//мы хотим добавить запись в "groups"
  with TForm2.Create(nil) do
  try
    if ShowModal = idOk then
    begin
      Str := Edit1.Text;
      Str1 := Edit2.Text;
    end else
      Exit;
  finally
    Free;
  end;
  //добавляем
  MySQL.ExecSQL(
       ' INSERT INTO `groups` (`name`,`desk`)'
     + ' VALUES ('
     +     MySQLStr(MySQL, Str) + ','
     +     MySQLStr(MySQL, Str1)
        + ' )');
  Id := MySQLInsertId(MySQL); //узнаём какой autoincrementный ID присвоила база новой записе
  if Id <> 0 then
  begin
    ListItem := lvGroups.Items.Add;
    ListItem.Caption := Str;
    ListItem.Caption := Str1;
    New(Data);
    Data.id := IntToStr(Id);
    ListItem.Data := Data;
  end;



А сейчас вопрос: Не выводит вторую колонку только после подключения помогите плиз!


26-11-2010 12:17
сообщение от автора материала
А путём поиска можно мыло обойтись без вот, путем проб и ошибок сделал...  - сообщение от "29-01-2008 05:18".
Ещё есть ответы как в обратную сторону.
 riff


26-11-2010 07:47
вот, путем проб и ошибок сделал код загрузки jpg изображения из blob поля через TMemoryStream, может кому будет полезно.


var imgStr:string;
    query_result: IMySQLQuery;
    streamImg: TMemoryStream;
    JpgImg: TJPEGImage;

...

       imgStr := query_result.ValueByName['photo'];
       streamImg := TMemoryStream.Create;
        try
          streamImg.Write(Pointer(imgStr)^, Length(imgStr));
          streamImg.Position := 0;
          JpgImg:=TJPEGImage.Create;
          try
            Img1.Picture.Graphic:=NIL;
            JpgImg.LoadFromStream(StreamImg);
            Img1.Picture.Graphic:=TJPEGImage.Create;
            Img1.Picture.Graphic.Assign(jpgImg);
           finally
             JpgImg.Free;
           end; //JpgImg
        finally
          streamImg.free;

        end;//streamImg
      



25-11-2010 02:11
В результате-то что случилось? Ты поправил код как в моём предыдущем сообщении (для версии 5.1), а взял dll 5.0 или ты ничего не правил, а с 5.0 не работает?

У меня несколько MySql серверов. Есть 5.0 и 5.1. Так вот подправил


  st_mysql_field = record
    name, org_name,
    table, org_table,
    db,
    catalog,
    def: PAnsiChar;
    length, max_length,
    name_length, org_name_length,
    table_length, org_table_length,
    db_length, catalog_length,
    def_length,
    flags, decimals,
    charsetnr: Cardinal;
    _type: enum_field_types;
    extension: pointer; //<———— в mysql.pas добавь эту строку
  end;


Скопировал dll, не заработало. Потом оказалось что это не та dll-ка была. Скопировал dll от Mysql 5.1 - все отлично работает.


24-11-2010 00:52
сообщение от автора материала
Сорри. Всё заработало. Оказалось что у меня libmysql.dll была версии 5.0
Я всегда знал, что проблему не надо решать сразу при её возникновении - через сутки она или сама отвалится или изменится :)
На самом деле мне письмо не пришло о новом сообщении в комментариях.


В результате-то что случилось? Ты поправил код как в моём предыдущем сообщении (для версии 5.1), а взял dll 5.0 или ты ничего не правил, а с 5.0 не работает?
 riff


23-11-2010 23:47
Сорри. Всё заработало. Оказалось что у меня libmysql.dll была версии 5.0


23-11-2010 07:45
Вот еще одна проблема. Использование структуры as в запросе вернет только один столбец, первый. Вот код измененный в демо, при нажатии на группу ничего не выведется


...
  'SELECT' + #13#10 +
    'id,' + #13#10 +
    'pid,' + #13#10 +
    'first_name as fn,' + #13#10 +
    'last_name as ln,' + #13#10 +
    'dr,' + #13#10 +
    'phone,' + #13#10 +
    'address' + #13#10 +
   'FROM' + #13#10 +
    'mydb_test.book' + #13#10 +
   'WHERE `pid`=' + GroupData.id
    );
    if query_result = nil then //если по какой-либо причине нам вернули "ничего"
    begin
      ShowMySQLError; //посмотрим что случилось
      Exit;
    end;
    //если же запрос выполнен,
    while query_result.FetchRow do //то пробежимся по записям
    begin
      ListItem := lvBook.Items.Add; //и заполним lvBook
      ListItem.Caption := query_result.ValueByName['fn'];
      ListItem.SubItems.Add(query_result.ValueByName['ln']);
      ListItem.SubItems.Add(query_result.ValueByName['dr']);
      ListItem.SubItems.Add(query_result.ValueByName['phone']);
      ListItem.SubItems.Add(query_result.ValueByName['address']);
      New(BookData);
      BookData.id := query_result.ValueByName['id'];
      BookData.pid := query_result.ValueByName['pid'];
      ListItem.Data := BookData;
    end;
...



03-04-2010 14:43
Действительно, все заработало! Спасибо,  riff


03-04-2010 07:21
сообщение от автора материала
Повторюсь, конструкция запроса 'SELECT * FROM' ...' обрабатывается отлично, запрос типа 'SELECT col1,col2.... FROM' возвращает только  "col1".
Скачал сейчас libmysql.dll 5.1. Проверил, демо-пример действительно перестал работать.
На самом деле данные все возвращаются нормально, просто описание поля чуть изменилось:

  st_mysql_field = record
    name, org_name,
    table, org_table,
    db,
    catalog,
    def: PAnsiChar;
    length, max_length,
    name_length, org_name_length,
    table_length, org_table_length,
    db_length, catalog_length,
    def_length,
    flags, decimals,
    charsetnr: Cardinal;
    _type: enum_field_types;
    extension: pointer; //<-------- в mysql.pas добавь эту строку
  end;


возможно есть ещё где-нибудь изменения в заголовках, но пока не сверял. А добавив эту строку, у меня демо заработал.
 riff


03-04-2010 06:44
Я этот пример привел для нагладности. На самом деле, вместо 'count' может быть любое значение. Повторюсь, конструкция запроса 'SELECT * FROM' ...' обрабатывается отлично, запрос типа 'SELECT col1,col2.... FROM' возвращает только "col1".


03-04-2010 06:17
сообщение от автора материала
1. Проверь название поля возвращаемое в запросе, как ни как count-это зарезервированное слово: "query_result.FieldName[1]" (не помню отсчёт полей начинается с нуля или единицы, если с единицы, то FieldName[2]).
2. Пока не проверил, но, на вскидку, исчезнет ошибка, если в запросе поле count заключить в такие ` кавычки?
 riff


03-04-2010 05:57
Здравствуйте! При использовании прилагаемой к компоненту библиотеки libmysql.dll все работало отлично пока на взял эту dll из MySql 5.1.
При запросе не всех данных таблицы, а части, происходит ошибка:
  
query_result := MySQL.Query('SELECT name,count FROM `groups`');
if query.FetchRow then  
begin
....Caption := query_result.ValueByName['name'];//Caption получено
....Caption := query_result.ValueByName['count'];// Ошибка
.....................


13-03-2010 07:02
Заработало!!! Причина в том, что переменную надо было объявлять не как тип класс, как тип интерфейс:

var
  MySQLConnect: TMySQL;  //не правильно!!!
  MySQLConnect: IMySQL;  //правильно!!!



13-03-2010 06:47
А я столкнулся с глюком, который скорее всего связан с COM. В отдельном модуле создаю глобальную переменную (чтобы можно было использовать ее во всех модулях):

var
  MySQLConnect: TMySQL;

Создаю ее в этом же модуле:

initialization
  MySQLConnect := TMySQL.Create;

А потом, когда удаляется компонент, полученный в результате операции Query удаляется и сам MySQLConnect. Я проверил поставив точки останова в деструкторе TMySQLQuery.Destroy;
И, например, код

var
  MySQL: IMySQLQuery;
begin
  MySQL := MySQLConnect.Query(SQL_SELECT_THEME_NAME);
  try
    if MySQL = nil then
      ErrorDlg;
    <<<>>>
  finally
    MySQL := nil;
    MySQLConnect.ExecSQL('SET CHARSET cp1251');//здесь ошибка!!!
  end;

выдает ошибку при вызове MySQLConnect.ExecSQL() после того, как MySQL:=nil; Даже если не присваивать nil, в другой процедуре все равно MySQLConnect.ExecSQL() выдаст ошибку с адресацией.

Что делать???


23-01-2010 07:27
сообщение от автора материала
Спасибо за положительный отзыв.

Правда пришлось "допилить" переведя с функций, возвращающих значения, на процедуры с Exception's при наличии ошибок.
На слух сложно воспринимать, что именно ты правил. Но вообще я специально не добавлял никаких exceptions, дабы оставаться ближе к оригиналу API. Проще, мне кажется, проверять возвращаемый функциями результат, чем обвешивать их try..except.
 riff


23-01-2010 06:32
Очень пригодилось.
Большое спасибо автору.

Правда пришлось "допилить" переведя с функций, возвращающих значения, на процедуры с Exception's при наличии ошибок.
Но все равно очень пригодилось.
Иногда (как в моем случае - пакетная перегрузка из DBF в "Мускул") DB компоненты это излишество и существенная потеря производительности. А low level API - то что доктор прописал!


30-10-2009 08:08
сообщение от автора материала
удаленному серверу нет подключения, и самое интересное то, что провайдерский сервер не даёт соединения э-э-э, в смысле? Т.е. стоит запрет на внешние подключения, но тебе всё равно хочется?
Перепробовал кучу mySQL-компонентов и везде один и тот результат. В таком случае ответ очевиден: можешь ещё кучу перепробовать...

Или доступ разрешён, но не соединяется?
 riff


30-10-2009 07:32
Столкнулся с такой-же проблемой, когда на локалхосте всё замечательно работает, а к удаленному серверу нет подключения, и самое интересное то, что провайдерский сервер не даёт соединения (пробовал через троих разных провайдеров). Проблема актуальная. Перепробовал кучу mySQL-компонентов и везде один и тот результат.
 ZEF


30-09-2009 07:20
сообщение от автора материала
дык надо не в файл,в Timage выводить.
или имелось ввиду через временный файл...

Можешь использовать TMemoryStream.

Если не трудно, то приведите пример как тот же test.jpg положить в блоб поле.
Я давно с блоб полями не имел дело, наизусть точно не скажу. На круглом столе таких примеров много. В поиск.
 riff


30-09-2009 04:45
Ок, нижеприведенный пример работает.
Если не трудно, то приведите пример как тот же test.jpg положить в блоб поле.
Спасибо!


30-09-2009 04:38
дык надо не в файл,в Timage выводить.
или имелось ввиду через временный файл...


30-09-2009 03:00
сообщение от автора материала

var
  query: IMySQLQuery;
  S: string;
begin
  query := MySQL.Query('SELECT * FROM ...');
  if query = nil then //если по какой-либо причине нам вернули "ничего"
  begin
    //ошибка
    Exit;
  end;
  if query.FetchRow then //или while query.FetchRow do //пробежимся по записям
  begin
    s := query.ValueByName['img'];
    with TFileStream.Create('f:\test.jpg', fmCreate) do
    try
      Write(Pointer(s)^, Length(s));
    finally
      Free;
    end;
  end;
end;

 riff


30-09-2009 01:59
не получается работать с блоб полями
вот пример (в блобе лежит картинка jpeg):

var
query_result: IMySQLQuery;
ii: TBlobField;
S: TMemoryStream;
begin
    S := TMemoryStream.Create();
    ii.value := query_result.ValueByName['img']; // вот тут происходит Access violation...
    ii.SaveToStream(s);
     try
      Img.Picture.Bitmap.LoadFromStream(S);
     finally
      S.Free;
     end; // try
end;

что не так делаю?
Спасибо!


03-09-2009 08:25
Да, хэшированными. если длина = 16, то в старом формате; длинней - в новом.

длина что-то в районе 40-50 символов, досчитал до 20, визуально прикинул остаток :)

Локально поставил мускуль 5.0, на удаленных серверах тоже он глубокая мысль :) Дна не увидел.

судя по всему, дно примерно где-то тут
MySQL 5.0 uses an authentication protocol based on a password hashing algorithm that is incompatible with that used by older (pre-4.1) clients.
Потому и сообщаю, что либа у меня от 5-й версии и коннекчусь к 5-ой версии же. При этом никаких дополнительных телодвижений с паролями не произвожу и, судя по размеру хэша, пароль сей нового образца. Размер файла libmysql.dll - 2 068 480 байт, данных о версии, к сожалению, внутри нет.


03-09-2009 02:56
сообщение от автора материала
Судя по той абракадабре, которую вывел select user,password from user - пароли хранятся уже хэшированные.
Да, хэшированными. если длина = 16, то в старом формате; длинней - в новом.

Локально поставил мускуль 5.0, на удаленных серверах тоже он глубокая мысль :) Дна не увидел.
 riff


03-09-2009 02:48
кстати: скачал, запустил демку, локально все красиво а локально у тебя в каком виде пароли? (База mysql/таблица user/колонка password). Или ты локально без паролей?

да нет, с паролями. Судя по той абракадабре, которую вывел select user,password from user - пароли хранятся уже хэшированные. Локально поставил мускуль 5.0, на удаленных серверах тоже он, и туда и туда коннект прошел нормально.


03-09-2009 02:24
сообщение от автора материала
а разве этот функционал не в libmysql.dll? Я думаю, что версия библиотеки должна совпадать с версией сервера, к которому поключаешься
Я свою libmysql взял из установочного пакета, но она всё равно подключается только к паролю старой версии. Я думал может какой-нибудь флаг при подключении есть или ещё чего. Ни чего не нашёл (хотя не сильно и искал). Будет чуть времени ещё раз поищу.

кстати: скачал, запустил демку, локально все красиво а локально у тебя в каком виде пароли? (База mysql/таблица user/колонка password). Или ты локально без паролей?
 riff


02-09-2009 12:14
http://dev.mysql.com/doc/refman/5.0/en/old-client.html
http://dev.mysql.com/doc/refman/5.0/en/password-hashing.html

Пока не въехал как заставить работать с новыми паролями. Если кто-то знает что делать подскажите...


а разве этот функционал не в libmysql.dll? Я думаю, что версия библиотеки должна совпадать с версией сервера, к которому поключаешься


02-09-2009 08:36
сообщение от автора материала
>>>Только сейчас сообразил - это мой айпишник в сообщении об ошибке, то есть меня не пускает
Ну, да :) Тоже только что проверил

>>>это как? чего-то такого не нашел.
http://dev.mysql.com/doc/refman/5.0/en/old-client.html
http://dev.mysql.com/doc/refman/5.0/en/password-hashing.html

Пока не въехал как заставить работать с новыми паролями. Если кто-то знает что делать подскажите...
 riff


02-09-2009 02:50
Сейчас только что проверил подключение к db4free.org(net), всё прошло успешно, данные загрузил.
Зарегистрируйся там тоже и проверь подключение.

да нет, у меня свои сервера стоят, есть на чем тестить :)

(При создании базы выбирай old_password, возможно и сейчас у тебя не коннектится к твоей из-за разниц нового и старого типов паролей).
это как? чего-то такого не нашел...

пытался и доменное имя вбивать вместо адреса - то же самое... почему последние два октета в сообщении об ошибке не соответствуют указанному адресу?
Без понятия. Единственное что могу предположить: может на базу стоит ограничение, что только с такого-то ip(или только из локальной сети) можно коннектится.


вообще-то ограничений нет. Только сейчас сообразил - это мой айпишник в сообщении об ошибке, то есть меня не пускает. Но самое интересное, что у меня на линуксе mysqlcc без проблем коннектится и никаких ошибок не выдает. В самой mysql в таблице юзеров есть запись для 'root'@'%' - я так понимаю, что это с любого айпишника можно цепляться


02-09-2009 00:17
сообщение от автора материала
получил очень интересный глюк - host xx.xx.132.147, при подключении обламывется с ошибкой
access denied for user 'root'@'xx.xx.130.124' (using password....

Сейчас только что проверил подключение к db4free.org(net), всё прошло успешно, данные загрузил.
Зарегистрируйся там тоже и проверь подключение. (При создании базы выбирай old_password, возможно и сейчас у тебя не коннектится к твоей из-за разниц нового и старого типов паролей).

пытался и доменное имя вбивать вместо адреса - то же самое... почему последние два октета в сообщении об ошибке не соответствуют указанному адресу?
Без понятия. Единственное что могу предположить: может на базу стоит ограничение, что только с такого-то ip(или только из локальной сети) можно коннектится.
 riff


01-09-2009 12:04
скачал, запустил демку, локально все красиво, но когда попытался в host прописать адрес из инета, на котором крутится мускуль - получил очень интересный глюк - host xx.xx.132.147, при подключении обламывется с ошибкой

access denied for user 'root'@'xx.xx.130.124' (using password....

пытался и доменное имя вбивать вместо адреса - то же самое... почему последние два октета в сообщении об ошибке не соответствуют указанному адресу?


25-08-2009 01:54
сообщение от автора материала
Илья: просьба писать вопросы по DataSet'ам в соответствующую ветку.
 riff


24-08-2009 16:34
Вот такая проблема...

Есть TdkMySqlConnection. Есть связанный с ним TdkMySqlDataSet. Есть TDBGrid, который через TDataSource связан с набором данных TdkMySqlDataSet.

Так вот.. При открытии набора данных TdkMySqlDataSet в Grid'е все текстовые поля отображаются пустыми - отображаются только BLOB и целочисленные данные. Что такое может быть?


16-08-2009 02:02
сообщение от автора материала
Для тех кто предпочитает работать с данными стандартными DB компонентами, написан TdkMySqlDataSet. Адрес статьи: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1407
 riff


15-08-2009 12:38
Прилагаемый к материалу файл "Классы и демонстрационный проект" обновлён.


27-07-2009 01:23
сообщение от автора материала
>>> нужен поиск по результату, который возвращает запрос. На основании этого поиска буду заполнять список.
TMySql - это удобная обёртка для mysql функций, не более того. Ни каких расширений функциональности я к ней писать не буду.
Вместо этого я написал потомка TDataSet'а, умеющего работать с TMySql, вот там можно искать, фильтровать, сортировать... точнее можно будет, как только его опубликуют. А пока напиши в личку e-mail я тебе его вышлю.
 riff


27-07-2009 00:57
riff, нужен поиск по результату, который возвращает запрос.
На основании этого поиска буду заполнять список.


27-07-2009 00:37
сообщение от автора материала
Билдер: Описанная тобой проблема это твоя проблема или TMуSQL?
>>>Как можно ограничить вывод значений (в идеале нужно выбрать минимальное, зная шаг и максимальное значение заполнить список и установить значение по умолчанию)?
Вот как ты сказал так и напиши у себя в программе.
>>>Нужны методы, аналогичные SetKey, GotoKey....
Какой SetKey? Какой GotoKey? Что за минимальный шаг? От куда выбрать? От куда мы взялись? (а не, последний вопрос из другой оперы).
 riff


27-07-2009 00:00
Использую компонент MуSQL. Таблица имеет следующую структуру:
параметр|значение_по_умолчанию|мин.|макс|шаг|
Загружаю инфо из базы в StringGrid. В StringGrid встроил ComboBox, в котором нужно отображать допустимые значения параметра. Для этого выполняю:

var
  query_result : IMySQLQuery;
  strSQLText   : string;
begin
...
  strSQLText := 'SELECT * FROM listParametr';
  query_result := form1.MySQL.Query(strSQLText);
....
  with form1.StringGrid1 do
  begin
....
        while query_result.FetchRow do //пробежимся по записям
        begin
              Cells[0, RowCount - 1] := (query_result.ValueByName['idList']);
              Cells[1, RowCount - 1] := (query_result.ValueByName['ListParametr']);
              Cells[2, RowCount - 1] := (query_result.ValueByName['ParametrValue']);

              // обработка для каждой строки
                    ComboBox1.Items.Add(Cells[2, RowCount - 1]);

              Cells[3, RowCount - 1] := (query_result.ValueByName['ParametrValueMax']);
              Cells[4, RowCount - 1] := (query_result.ValueByName['ParametrValueMin']);
        end;
              RowCount := RowCount - 1;  // пустую строку (последнюю) скрываем
end;
end;


При таком подходе в ComboBox1 отображаются все значения, хранимые в поле ParametrValue. Как можно ограничить вывод значений (в идеале нужно выбрать минимальное, зная шаг и максимальное значение заполнить список и установить значение по умолчанию)? Нужны методы, аналогичные SetKey, GotoKey.


18-07-2009 05:04
сообщение от автора материала
ART-of-FaNtAsY:
1. Спасибо за "спасибо" :)
2. У себя на ноуте сносить MySql, чтобы проверить, не хочется, но судя по тому, что на работе народ коннектится к базе в локальной сети, то можно.
3. Напиши в личку e-mail пришлю обновление. (в королевстве задержка какая-то).
 riff


18-07-2009 04:50
Отличный класс.
Скажите, а можно ли использовать его для работы со встроенным сервером? Т.е. подключаться к базе данных MySQL при помощи библиотеки libmysqld.dll, не устанавливая сам сервер.


04-05-2009 03:40
сообщение от автора материала
Кроме как проверь
* mysql.Host
* mysql.User
* mysql.Password
* mysql.Database
сказать больше ничего не могу. У меня коннектится и в localhost'те и в сети к серверной(на линуксе) и к какой-то в инете.

У mysql есть консольная оболочка, через неё коннектится? (я не жду ответа на этот вопрос :) это ты сам себя спроси.)
 riff


03-05-2009 08:06
MySQL поставил вместе с денвером


03-05-2009 08:03
На localhost все ок а по сети не могу приконектиться. Что это может быть? Фаервол отключен. Антивируса нет


20-04-2009 11:38
>>> Спасибо большое также riff'у за совет: сам с такой проблеммой столкнулся,
>>> весь вечер на нее убил. А все оказалось очень просто.)
За какой? Твоих вопросов (с ником Anafor) здесь не встречается.

Прошу прощения, за этот совет:
25-01-2008 08:47
Ну вот и нашли твою ошибку... Должно быть MySQL: IMySQL;
MySQL - это интерфейсная ссылка. А ты, объявив её как объект, выходя из процедуры, где её инициализируешь, просто напросто теряешь. И соответственно никаких mysql.free в конце работы не надо. И то что Один раз у тебя получается сделать селект - это чистая случайность.

Объяви как MySQL: IMySQL; и радуйся жизни. :)



11-03-2009 01:20
сообщение от автора материала
[i]* извините, у второго ответа форматирование сбил[/i]

Anafor:
>>> Спасибо огромное автору! Все очень удобно и продуманно.
У "компонент" два автора, кому из них "спасибо"? :-)
>>> Спасибо большое также riff'у за совет: сам с такой проблеммой столкнулся,
>>> весь вечер на нее убил. А все оказалось очень просто.)
За какой? Твоих вопросов (с ником Anafor) здесь не встречается.
 riff


11-03-2009 01:16
сообщение от автора материала
Mike:
>>> как я понял из ответа в DBGrid (или даже SrtingGrid)
>>> нужно подставлять данные только с помощью запросов.
В DBgrid не получится т.к. он работает с TDataSet/TDataSource. А в TStringGrid, ListBox, ListView, TreeView,... пожалуйста.
>>> Можно ли при использовании MySQLClasses.pas
>>> определить значение DataSource, чтобы заполнить свойство DBGrid?
Был(есть?) такой простенький компонент что-то вроде VirtuaDataset. Он не хранит данные в себе, но по необходимости запрашивает их у тебя (т.е. в данном случае ты их отдаёшь из IMySQLQuery).
Есть подобные же (кажется TMemDataset): после выборки все данные заталкиваешь в такой потомок Dataset'а и далее уже прикручиваешь DBGrid и т.п.


Anafor:b]
>>> Спасибо огромное автору! Все очень удобно и продуманно.
У "компонент" два автора, кому из них "спасибо"? :-)
>>> Спасибо большое также riff'у за совет: сам с такой проблеммой столкнулся,
весь вечер на нее убил. А все оказалось очень просто.)
За какой? Твоих вопросов (с ником Anafor) здесь не встречается.
 riff


05-03-2009 21:16
>Нет нельзя, это низкоуровневая библиотека никак не связанная со >стандартными Delphi компонентами типа TDataSource.

как я понял из ответа в DBGrid (или даже SrtingGrid) нужно подставлять данные только с помощью запросов.


05-03-2009 16:23
Спасибо огромное автору! Все очень удобно и продуманно.
Спасибо большое также riff'у за совет: сам с такой проблеммой столкнулся, весь вечер на нее убил. А все оказалось очень просто.)


05-03-2009 11:14
Нет нельзя, это низкоуровневая библиотека никак не связанная со стандартными Delphi компонентами типа TDataSource.
 DRON


05-03-2009 09:16
Уважаемые коллеги!

Можно ли при использовании MySQLClasses.pas
определить значение DataSource, чтобы заполнить свойство DBGrid?


03-02-2009 11:29
:DRON
да, Вы правы, это один из способов, но он повлечет за собой ненужную дисковую активность, ненужные операции записи и чтения на/с диска и, как сдедствие, общее снижение быстродействия.
В случае с recordset.getstring этого как раз удается избежать и происходит все очень быстро и четко.
Я хотел бы сделать то же самое, но еще и избавившись от ADO/ODBC, удалив еще одно лишнее звено, хотя бы применительно к MySQL.
Кстати, вы не знаете, существует ли такой нативный, без odbc, способ работы с mssql?
Сами результирующие таблицы в csv я обрабатываю в собственном табличном движке в оп.памяти и там единичные задержки радко вылезают за тот интервал, который я могу качественно измерить даже при помощи высокоточных таймеров.


03-02-2009 05:21
sane, почитайте про "SELECT ... INTO OUTFILE" в справке на MySQL, может оно вам и подойдёт.
 DRON


02-02-2009 19:50
вопрос:
в ADO есть метод recordset.getstring,
позволяющий получить весь результат запроса в виде стринга, например, как csv, отформатировав результирующую табличку соответствующим образом.

как бы сделать то же самое с использованием этого компонента / получить это от libmysql другим способом?

т.е. мне нужно получить содержимое всей таблички в виде стринга/стрима/итд целиком, не дергая по ячейке/ряду.


20-12-2008 09:30
сообщение от автора материала
* ну и естественно в конце каждой строки точка с запятой.
 riff


20-12-2008 09:16
сообщение от автора материала
Я подобными перечислениями никогда не пользовалься, возможно это можно переписать как
type
  MYSQL_SHUTDOWN_LEVEL = byte;
const
  SHUTDOWN_DEFAULT: MYSQL_SHUTDOWN_LEVEL = 0;
  SHUTDOWN_WAIT_CONNECTIONS: MYSQL_SHUTDOWN_LEVEL = 1,
  SHUTDOWN_WAIT_TRANSACTIONS: MYSQL_SHUTDOWN_LEVEL = 2,
  SHUTDOWN_WAIT_UPDATES: MYSQL_SHUTDOWN_LEVEL = 8,
  SHUTDOWN_WAIT_ALL_BUFFERS: MYSQL_SHUTDOWN_LEVEL = 16,
  SHUTDOWN_WAIT_CRITICAL_BUFFERS: MYSQL_SHUTDOWN_LEVEL = 17,
  KILL_QUERY: MYSQL_SHUTDOWN_LEVEL = 254,
  KILL_CONNECTION: MYSQL_SHUTDOWN_LEVEL = 255
если я не прав, меня поправят.

>>>[Error] MySQL.pas(136): Undeclared identifier: 'PLongWord'
type
  PLongWord = ^LongWord;q
 riff


19-12-2008 03:44
Ну при компиляции сразу дает ошибку в модуле MySql.pas

Наверное, у вас старая версия Delphi, которая ещё не понимает перечислений с указанием значений - это оносительно недавнее расширение, появилось не то в D6, не то в D7.


19-12-2008 02:07
Ну при компиляции сразу дает ошибку в модуле MySql.pas:
[Error] MySQL.pas(105): ',' or ')' expected but '=' found
вот на этот кусок кода:
MYSQL_SHUTDOWN_LEVEL = (SHUTDOWN_DEFAULT = 0,
    SHUTDOWN_WAIT_CONNECTIONS = 1,
    SHUTDOWN_WAIT_TRANSACTIONS = 2,
    SHUTDOWN_WAIT_UPDATES = 8,
    SHUTDOWN_WAIT_ALL_BUFFERS = 16,
    SHUTDOWN_WAIT_CRITICAL_BUFFERS = 17,
    KILL_QUERY = 254,
    KILL_CONNECTION = 255
  );

и еще говорит: [Error] MySQL.pas(136): Undeclared identifier: 'PLongWord'
вот сздесь: return_status: PLongWord;


27-11-2008 10:52
сообщение от автора материала
Cyber: да вроде бы ничего такого что не должно работать в Delphi5 в компоненте нет... не работает это что значит: не компилится или где? мой пример тоже не работает? какие ошибки и в каком месте.
как переделать? правильно заданный вопрос - половина ответа.
 riff


27-11-2008 10:42
сообщение от автора материала
noname извини, твоё сообщение не видел ваше.
а ты читал ответ от 20-11-2007 11:47 может в этом дело?
 riff


27-11-2008 06:19
Данный компонент не работает в Delphi5 !
как переделать?
или есть другая версия?


04-11-2008 18:34
Спасибо автору ,но есть пара вопросов,(извените ламера delphi), есть код


type
   ...
   private
    mysql_link: imysql;
    procedure mysql_error();
  end;
...
mysql_link:=TMySQL.Create;
...
mysql_link.Host:= host;
mysql_link.User:= user;
mysql_link.Password:= pass;
mysql_link.Port:= port;
  if not mysql_link.Connect then mysql_error();
mysql_link.Database:= database;
...
   query_str:= 'SELECT privileges.id AS `id`,'
                     +' privileges.user_id AS `user_id`,'
                     +' privileges.login AS `user_login`,'
                     +' privileges.add_price AS `add`,'
                     +' privileges.ch_price AS `change`,'
                     +' privileges.del_price AS `delete`,'
                     +' users.last_login AS `last_login`,'
                     +' users.prersent AS `prersent`,'
              +'FROM privileges, users WHERE users.id=privileges.user_id'
                    +' AND users.pass = '+ u_pass;
   mysql_query:= mysql_link.Query(query_str);
   while mysql_query.FetchRow() do
    begin
     info.add('id',mysql_query.ValueByName['id']);
     ...
    end;


но при выполнении mysql_query.FetchRow() возвращает nil. В БД всё есть, проверял запрос в консоли, всё правельно извлекаетса, авделфях нехочет, все данные или VARCHAR или INT. dll от мускуля в папке с поектом и в %SystemRoot%, что это может быть? конект к БД есть, т.к. execsql работает. А и mysql_query(mysql: pmysql; q: PChar) возвращает 0, + похожая выборка в другом месте отлично работает!

С уважением


19-10-2008 17:43
Большое спасибо, ч полезная весчь.


08-10-2008 13:51
Автору спасибо. Лучшее из того, что я видел.
Но, всё же, есть одна недоработка.

При соединении с MySQL функцией mysql_real_connect() последним параметром (флаг) передаётся 0. В результате нельзя отправить запрос CALL proc_name и вызвать процедуру, которая возвращает набор данных. Более того, почему-то в модуле mysql.pas просто нет константы CLIENT_MULTI_STATEMENTS, которую нужно передать в качестве последнего флага для того, чтобы можно было получать набор данных.
И как тут быть? Получается, эта возможность не реализована?


14-08-2008 01:01
Большое спасибо! Очень удобный и ОЧЕНЬ нужный компонент


13-08-2008 22:12
Отличный компонент! Это то, что я искал.
Всё гениально и просто!
Большое СПОСИБО автору - сэкономил мне кучу времени и нервов :)


26-03-2008 10:47
люди добрые дайте плиз домонстрационный проект для записи\ считывания изображений в\из базы.

будет ли отличие по скорости если использовать другие компоненты, например, myDac?


09-03-2008 06:00
сообщение от автора материала
Скорей всего ты неверно вводишь логин или пароль или host. необязательно же у всех на локальном компе user=ODBC, у меня, например, user=root. А если ты пытаешься подключиться к удалённой mysql, то почему вводишь host=localhost, там должно быть что-то типа "217.54.2.33" (т.е. ip с которого видна база)
 riff


08-03-2008 17:47
этава...на моем домашнем компьютере, программа с libMysql.dll идёт и работает отлично.
на остальных - вылазит ошибка access denied for user ODBC@localhost using password - NO...вот...может там необходими еще библиотеки кроме одной?


05-02-2008 22:33
Я тебе отправлял дамп базы,
ты таки залей ее себе, проверь считывает ли битмап из нее
если все ок- значит у меня читает криво
если нет- значит запись кривая


05-02-2008 12:31
сообщение от автора материала
5.0.45 не нашёл, скачал 5.0.51а. Запустил присланный тобой тестовый проект... угадай результат... Всё работает без проблем.
Счастливчик ты наш :)
 riff


05-02-2008 10:06
Возможно у него чуть старше версия и может там был какой-нибудь глюк, не знаю.
У меня 5.0.45 comunity-nt


04-02-2008 04:53
сообщение от автора материала
Попробовал ещё раз перечитать сообщение Serg. Похоже я тоже не до конца понял смысл.
Получается что-то вроде:
один наговорил текст, отправил.
у второго раз в секунду(например) программа проверяет нет ли новых сообщений, если есть воспроизводит.
?
Тогда в чём сложность? Ладно проехали. Там скорее дело техники, а не способа хранения.
 riff


04-02-2008 04:30
сообщение от автора материала
На счёт картинки которая вызывала AV у Арсения.
Он мне прислал эту картинку и тестовый проект - я этот проект скомпилировал, запустил, добавил картинку затем её прочитал, проблем никаких нет (У меня версия MySql: Server version: 5.0.41-community-nt MySQL Community Edition). Возможно у него чуть старше версия и может там был какой-нибудь глюк, не знаю. Я пробовал запихивать различное содержание в блоб - ни разу не получилось получить некорректные данные.
 riff


04-02-2008 04:29
Riff, спасибо за ответ! Наверное так и должно быть - каждому софту свои задачи и нагромождать его универсальностью это, скорее всего, пойдет в ущерб основной его функциональности! Вопрос снимаю всем спасибо!


04-02-2008 04:16
сообщение от автора материала
Возможно ли, используя MySql, осуществить голосовое общение между пользователями - аля Skype? Вот чесно скажу никогда даже случайной мысли такой не было и думать над этим нет никакого желания :)
Единственное что мелькнуло во время чтения сообщения это разрезать медиа на кусочки, записать, и затем их подгружать... записать первую часть в файл, натравить плеер, загрузить вторую часть, записать,.... (не знаю как работает плеер)
Моё мнение - не для этого нужна база, не для хранения медия и т.п. А медиа ты мог бы с тем же успехом загружать(подзагружать) и по HTTP (Indy TidHTTP).
 riff


04-02-2008 04:16
Geo, а как по вашему устроена работа Skype, ведь он использует сорость(интернета), которая во многих случаях еще далека от скорости сети? В нем тоже создаются эккаунты и т.д., т.е. без сервера БД, я думаю, там не обходятся. А представьте ситуацию, когда у предприятия еще нет интернет подключения, но зато есть обычная сеть, которая, как я указывал, быстрее многих интернет подключений, а рабочие места менеджеров расположены по отдельным зданиям... Просто наверное этого... никто еще не делал, тому как есть много другого ПО, которое обеспечивает данный сервис!


04-02-2008 03:50
>>> <...> скорость воспроизведения блобМедиаДанных меньше, чем скорость их передачи
Ну, чтобы медитаданные из блоба воспроизвести, их надо сначала в этот блоб положить. А уж пара операций (сохранение и считывание) всяко потребует больше затрат времени, чем непосредственная передача.

А в целом по вопросу... знаете, я меатериалист и считаю, что чудес на свете не бывает. А если бывает, значит мы что-то не учли. Если сервер с MySQL ухитряется вытаскивать из блоба данные и передавать их на клиента быстрее, чем клиенты обмениваются данными между собой, то это может говрить либо о качестве канала, либо о качестве механизма передачи.
 Geo


04-02-2008 03:38
Geo, предположим, что есть проект, в котором один менеджер по продажам обнаруживает, что товар, который он хотел продать зарезервирован другим менеджером по продажам. В этом случае неплохо было бы, если предоставлялась этим проектом возможность пообщаться с ним. То, что хранилище данных..., так никто об этом и не спорит. А натолкнуло меня на этот, пусть для вас и ламерский вопрос, так это одно "наблюдение" - скорость воспроизведения блобМедиаДанных меньше, чем скорость их передачи. ТОлько, вот, как это сделать, у вы, не знаю, почему и HELP me........!


04-02-2008 03:16
>>> Возможно ли, используя MySql, осуществить голосовое общение между пользователями - аля Skype?
Извините, что влезаю в вашу беседу, но причем тут MySQL? MySQL -- это СУБД. Хранилище данных. Вопрос примерно того же плана, как можно ли использовать трехдюймовые дискеты для осуществления голосового общения между пользователями.

Или я неправильно понял Ваш вопрос?
 Geo


04-02-2008 03:08
Добрый день, Riff!
Пока все..... нормально!
Извините за наглость, но у меня такой вопрос:
Возможно ли, используя MySql, осуществить голосовое общение между пользователями - аля Skype?
Как вы поняли - я в делфях еще не очень..., хотя бы подскажите посредством чего это можно решить. Ну, а если по слогам..., то это вообще - суппер было бы!
Заранее благодарю!



31-01-2008 10:44
сообщение от автора материала
Арсений, утром я написал тебе, что жду от тебя проблемную картинку(AV)... ну и?!
 riff


31-01-2008 06:14
1. Не пренебрегайте чистотой кода:


  if q.FetchRow() then //раз ты выбрал только одну запись, то, в данном случае, if
  begin
    tempStr := q.Values[0];


Эт я на скорую руку писал, уж простите..

*  А ТАМ ГДЕ выскакивает ошибка - это точно bitmap? не jpeg?
Да, точно битмап. Сначала я попробовал jpeg, но потом понял, что изза этого косяк..

*  ВСЕГДА ЛИ эта картинка является проблемной? т.е. нет такого что сейчас открылась, а в другой раз AV?
Да, всегда.. если вылетает AV- то всегда вылетает. Если работает- всегда работает.
то загружет битмап, но какой то поврежденный
Это вообще интересно выглядит... картинка из базы загружается с потерей некоторых цветов... Я вообще удивился..
(Вот такая поврежденная картинка- это стандартная виндовозовская "ЦИНОВКА")


31-01-2008 00:34
сообщение от автора материала
иначе создай новый проект, ... блин, не дописал. Ну естественно пришли мне его(сурсы).
 riff


31-01-2008 00:30
сообщение от автора материала
1. Не пренебрегайте чистотой кода:


  q:=mysql.Query('SELECT blobfield FROM test.t1 WHERE ID=1');
  if q=nil then
  begin
    memo1.Text := Format('Ioeaea #%d '#13#10' %s', [MySQL.ErrorCode, MySQL.ErrorMessage]);
    Exit;
  end;
  if q.FetchRow() then //раз ты выбрал только одну запись, то, в данном случае, if
  begin
    tempStr := q.Values[0];
    ....//остальные строки из процедуры



2. Сейчас, скорей всего, ошибка не из-за этого....
*  А ТАМ ГДЕ выскакивает ошибка - это точно bitmap? не jpeg?
*  ВСЕГДА ЛИ эта картинка является проблемной? т.е. нет такого что сейчас открылась, а в другой раз AV?
*  Если картинка ВСЕГДА проблемная, то пришли мне ЕЁ, иначе создай новый проект, сделай там только коннект, вставку/чтение записи, пару-тройку тестовых картинок и sql комманду "create table ..." в которой тестируешь. (Сам только сначала протестируй чтобы гарантированно получался AV) (также вложи свою версию libmysql.dll и mysql.pas/mysqlclasses.pas).
 riff


30-01-2008 13:27
p.s. Арсений, у тебя-то хоть записываются/считываются?
записываются :)
но не считываются... что я неправильно сделал не знаю, но:
когда записывается- всегда без проблем,
когда считывается- то вылетает AV(на месте LoadFromStream), то Вылетает "Invalid Bitmap Data.."(или чтото такое), то загружет битмап, но какой то поврежденный, а иногда- все нормально, как записал, так и считал без ошибок.
Вариант ошибки зависит от файла.. одну bmp нормально сохраняет, другую криво.. :(
Вот две процедуры:


// To Blob
procedure TForm1.Button8Click(Sender: TObject);
var
  a, b: string;
  s: TMemoryStream;
  i:integer;
begin
s:=TMemoryStream.Create;
img.Picture.Bitmap.SaveToStream(s);
s.Position := 0;
  try
    SetLength(a, s.size);
    s.Read(pointer(a)^, length(a));
  finally
    s.Free;
  end;
  SetLength(b, length(a)*2);
  i:=mysql_real_escape_string(MySQL.MySQL, Pointer(b), Pointer(a), length(a));
  SetLength(b, i);
  if mysql.ExecSQL('REPLACE INTO test.t1(ID,blobfield) VALUES (1,'''+b+''')') then showmessage('OK')
  Else
  memo1.Text := Format('Ioeaea #%d '#13#10' %s', [MySQL.ErrorCode, MySQL.ErrorMessage]);
end;




// From blob
procedure TForm1.Button9Click(Sender: TObject);
var
  tempStr: string;
  stream: TMemoryStream;
q: IMySQLQuery;
begin
  q:=mysql.Query('SELECT blobfield FROM test.t1 WHERE ID=1');
  if q=nil then
  memo1.Text := Format('Ioeaea #%d '#13#10' %s', [MySQL.ErrorCode, MySQL.ErrorMessage]);
  WHILE q.FetchRow() Do
  tempStr := q.Values[0];
  stream := TMemoryStream.Create;
  try
    stream.Write(Pointer(tempStr)^, Length(tempStr));
    stream.Position := 0;
    img.Picture.Bitmap := TBitmap.Create;
    img.Picture.Bitmap.LoadFromStream(stream);// Здесь часто вылетает Access Violation
  finally
    stream.free;
  end;
end;



30-01-2008 10:33
Все Ок!!!!!!!!!!!!!!!!!!!!!!!!!
Riff? вы гений!
Оказывается я невнимательно все читал!
Спасибо вам большое, свою "функцию" я уже выбросил!


30-01-2008 09:52
сообщение от автора материала
давай по слогам разбираться:
20-11-2007 11:47
в файле MySql.pas заменить описание этой функции:

...
function mysql_fetch_lengths(result: pmysql_res): Pointer; stdcall;
...
implementation
...
function mysql_fetch_lengths(result: pmysql_res): Pointer; stdcall; external libmySQL;
...


в файле MySQLClasses.pas заменить
function TMySQLQuery.GetValues(FieldNo: Integer): string;
на функцию
из ответа 20-11-2007 11:47

Каково было мое удивление, когда я понял, что в блобе оказывается не экранированные данные после mysql_real_escape_string, а изначальные, как до экранирования(var а). Т.е. сервер преобразовал их в изначальный вид И ЭТО ПРАВИЛЬНО. ТАК И ДОЛЖНО БЫТЬ.

Т.е. билет в одну сторону, чтобы читать назад..., нужен новый "билет". Нет, ничего больше не нужно. просто select * from mytable.

Полученную строку из стрима экранирую, но не mysql_real_escape_string, а своей функцией, от проблемных символов и передаю ее в блоб простым MySql запросом. выброси свою функцию. делай только так как я расписывал ранее.

действуй. я сегодня уже врятли отвечу. до завтра.

p.s. Арсений, у тебя-то хоть записываются/считываются?
 riff


30-01-2008 08:51
var
  a, b: string;
  fs: TFileStream;
begin
  fs := TFileStream.Create('myfile.bmp', fmOpenRead or fmShareDenyWrite);
  try
    SetLength(a, fs.size);
    fs.Read(pointer(a)^, length(a));
  finally
    fs.Free;
  end;

  SetLength(b, length(a)*2);
  i:=mysql_real_escape_string(MySQL.MySQL, Pointer(b), Pointer(a), length(a));
  SetLength(b, i);
end;


Riff, все правильно, но я постараюсь объяснить - почему я назвал эту функцию(mysql_real_escape_string) односторонней:

Каково было мое удивление, когда я понял, что в блобе оказывается не экранированные данные после mysql_real_escape_string, а изначальные, как до экранирования(var а). Т.е. сервер преобразовал их в изначальный вид, что и делает эту функцию односторонней. Т.е. билет в одну сторону, чтобы читать назад..., нужен новый "билет". Извините за отвлечение, но если не купить новый билет, то в результате, как я указывал ранее, при чтении картинки в query_result.ValueByName['image'] мы максимум, что получаем, так это 4 символа, например, 'яШяа' и все. Очевидно, сервер спотыкается при первой встрече с   управляющими(или проблемными для него) символами. Еще я заметил эти первые 'яШяа' у каждого типа картинок свои, например, вышеуказанный относится к '*.jpg'. Может на стороне сервера и есть какие либо методы(билет) типа mysql_real_escape_string, но я о них, к своему стыду, ничего не знаю.

На данный момент, чтобы решить эту проблему я делаю так:

Полученную строку из стрима экранирую, но не mysql_real_escape_string, а своей функцией, от проблемных символов и передаю ее в блоб простым MySql запросом. В результате в блобе оказываются данные, которые при их чтении легко располагаются во все том же query_result.ValueByName['image'], поскольку не содержат клятых проблемных.... Вы правильно заметите, что в таком случае query_result.ValueByName['image'] не есть картинка и будете правы. Поэтому приводим ее в первоначальное состояние деэкранированием - функция обратная функции экранирования.

Я не считаю свой метод правильным, да и согласен с вами, что SQL запрос небезразмерен, поэтому к вам просьба:
Если у вас получилось ЧИТАТЬ картинку другими методами, просьба показать примерчик.

Спасибо за ответы!


30-01-2008 05:22
сообщение от автора материала
но теперь, в свете написанного ниже все встало на свои места и прояснилось. есть новость и совет. не берусь сказать плохие они или нет... так себе.
Не смотря на размер данных, способное вместить блоб поле, вам врятли удастся передать в sql комманде данные большого размера. (у меня сейчас получилось картинку вместить что-то около 500кило).
Может это где-то в настройках меняется, может ещё как-то - незнаю.

Совет: хранить картинки или другие бинарные данные в блобе не есть хорошо вообще, и гонять их по сетке "select * from mytable" в часности. их надо сваливать в отдельную папочку и передавать только по желанию. (имена же им давать "уникальный_номер_записи.расширение")
 riff


30-01-2008 04:54
Извините, что не отвечал, просто не было времени заглянуть на страничку.
Спасибо за замечания, сейчас буду пытаться воплотить ваши пожелания. О результатах обязательно сообщу.


30-01-2008 04:51
сообщение от автора материала
Такого вопроса небыло, но, возможно, у кого-то всплывёт эта "проблемка".
MySQL хранит дату в формате год-месях-день, что правильно с точки зрения сортировки, россиянам привычней читать на экране дату в формате день.месяц.год

var
  FormatSettings: TFormatSettings;
  Date: TDateTime;
begin
  FormatSettings.ShortDateFormat := 'yyyy-mm-dd'; //в данном случае срабатывает ShortDateFormat
  FormatSettings.LongDateFormat := 'yyyy-mm-dd'; //не помню по памяти на какой формат срабатывает long date, но на всякий случай
  FormatSettings.DateSeparator := '-';
  date := StrToDate('1970-05-10', FormatSettings);
  ...//что-то с этой датой делаем
  str := DateToStr(date); //наш формат
  str := DateToStr(date, FormatSettings); //обратно mysqlевский формат
end;

 riff


30-01-2008 04:19
Очередной раз большое спасибо, riff!
Теперь все доступно и понятно...
Я просто не понимал, как к запросу приклеить string с бинарными данными к SQL запросу...
Про экранирование и использование hex- очень к месту совет..
По поводу красного словца: прошу меня простить, я подобрал не то выражение, какое следовало бы..
Просто пример был мне не понятен, но теперь, в свете написанного ниже все встало на свои места и прояснилось. :)


30-01-2008 02:43
сообщение от автора материала
Если у кого то есть готовые функции для записи/чтения потока из блоба, то отпостите их, пожалуйста... Вчера же чёрным по серому написал чтение из блоба в поток, с последующим выводом в timage и в файл "29-01-2008 05:18".
 riff


30-01-2008 02:31
сообщение от автора материала
Теперь по поводу: Функция mysql_escape_string не подходит, так как односторонняя. ты просто не умеешь её готовить...

var
  a, b: string;
  fs: TFileStream;
begin
  fs := TFileStream.Create('myfile.bmp', fmOpenRead or fmShareDenyWrite);
  try
    SetLength(a, fs.size);
    fs.Read(pointer(a)^, length(a));
  finally
    fs.Free;
  end;

  SetLength(b, length(a)*2);
  i:=mysql_real_escape_string(MySQL.MySQL, Pointer(b), Pointer(a), length(a));
  SetLength(b, i);
end;


INSERT INTO ... VALUES (..., "' + b + '")
 riff


30-01-2008 02:13
сообщение от автора материала
Если честно, я вообще очень смутно представляю, как можно передать последовательность байтов..

function StrToHex(const Text: String): String;
begin
  if Text = '' then
  begin
    Result := '';
    Exit;
  end;
  SetLength(Result, Length(Text) * 2);
  BinToHex(Pointer(Text)^, Pointer(Result)^, Length(Text));
end;


Считываешь в строку данные из файла. превращаешь строку в hex с помощью этой функции.
Ведь в этой последовательности может быть и нулевой символ.. у строки(string) нет ограничения на символы.
 riff


30-01-2008 01:58
сообщение от автора материала
Я так понимаю, чтение из блоба, хоть и через пень-колоду, все таки реализуется.. Ради красного словца, не пожалеем...
А чем вас не устроило чтение из блоба? Вы не знаете что делать с полученной строкой?
 riff


30-01-2008 01:36
сообщение от автора материала
Все работает, если предварительно кодировать картинку от проблемных символов, а затем, соответственно, декодировать. Ну, наверно не кодировадь, а при вставке экранировать? надо просто в мануале почитать какие символы и как экранируются (например #0->\0, #10->\r, #13->\n), там их не много. А декодировать ничего не надо...

Написал свою, немного увеличивает объем данных, зато все без проблем работает. Т.е. в итоге в блобе информации больше чем нужно? ~:| См.выше.

Тогда все Ок. Иначе после фетча  query_result.ValueByName['image'] дает только первых несколько бряков, которые, как я понял не проблемные. Скорей всего ты в данном случае не прав. ValueByName должна возвращать строку не смотря на то какие там символы.

Например PhpMyAdmin при эспорте позволяет записывать блох в шестнадцатеричное отображении ну т.е. в HEX.
В Delphi есть функция BinToHex(кажется называется), которая превратит все символы переданного ей буфера в hex последователности и твой insert превратиться что-то подобное

INSERT INTO `book` (`pid`, `first_name`, `last_name`, `dr`, `phone`, `address`, `image`) VALUES
(1, 'Имя 1 2', 'Фамилия 1 2', '1970-02-02', '123-45-62', 'Город: ABC; улица: DEF; дом: 2', 0x424d3a1703000)


где 0x424d3a1703000 это
* 0x начало данных - это ты вставляешь сам
* 424d3a... - сами данные "BM:..." - это твоя картинка ввиде hex строки
ничего экранировать не надо, кавычек не надо, извлекаются данные также как я писал в пред.постах.
 riff


30-01-2008 00:22
Вопрос с блобами меня также все еще интересует... мало того, я до сих пор не знаю, как записать стрим в блоб...
и как я понял, со считыванием обратно тоже какие то проблемы...
Я в работе с разного рода указателями , памятью и тд не мастак, поэтому слегка парюсь..
Если у кого то есть готовые функции для записи/чтения потока из блоба, то отпостите их, пожалуйста...


Ежели ни у кого нету, то давайте писать вместе...
Я так понимаю, чтение из блоба, хоть и через пень-колоду, все таки реализуется..

Я вопрос о блобах задавал собственно автору этих компонент(Виталию Лещенко), которые были потом чуть чуть изменены автором этой статьи...
Вот цитата из его ответа:
Работа с блобами и другими бинарными данными требует дополнительных действий.
   Эти действия выполняются с помощью методов:
   function BinaryToString(const p: Pointer; size: Integer): string;
   procedure StringToBinary(const s: String; p: Pointer; out size: Integer);


Видимо речь шла как раз о том, что и сделал своими руками уважаемый Serge
Если честно, я вообще очень смутно представляю, как можно передать последовательность байтов..
Что, прямо внутри SQL-запроса?
Ведь в этой последовательности может быть и нулевой символ..
Теперь вы меня извиняйте за ламерские вопросы... ну не понимаю я технологию..


29-01-2008 13:52
Извините, но опять по поводу картинки из bloba!

var
  tempStr: string;
  stream: TMemoryStream;
begin
  tempStr := query_result.ValueByName['image']; //предположим ваш blob называется image
  stream := TMemoryStream.Create;
  try
    stream.Write(Pointer(tempStr)^, Length(tempStr));
    stream.Position := 0; // не забывайте обнулять позицию stream
    //отобразим в TImage
    Image1.Picture.Bitmap := TBitmap.Create;
    Image1.Picture.Bitmap.LoadFromStream(stream);
    //сохраним на диске
    stream.Position:=0;
    stream.SaveToFile('c:\b.bmp');
  finally
    stream.free;
  end;
end;


Все работает, если предварительно кодировать картинку от проблемных символов, а затем, соответственно, декодировать. Тогда все Ок. Иначе после фетча  query_result.ValueByName['image'] дает только первых несколько бряков, которые, как я понял не проблемные. Функция mysql_escape_string не подходит, так как односторонняя. Написал свою, немного увеличивает объем данных, зато все без проблем работает. Пишу это все потому, как думаю, что "зубы почистил через нос", не верится, что такой инструмент с блобами проще не работает. Скорее всего я просто не знаю, как это... сделать. Если кто знает просьба примерчик.


29-01-2008 07:16
Арсений, еще раз благодарю вас! Я приобрел - MySql Поль Дюбуа третье издание, но с удовольствием воспользуюсь вашими источниками.


29-01-2008 07:14
PS: Serge, ты меня на 4 года старше... думаю обращение "на ты" будет вполне уместным)))))))))


29-01-2008 07:10
:) Да я сам неделю назад первый раз столкнулся с Мускулом.. Сам ламер из ламеров...
Я собственно в основном всю информацию беру из двух книжек.. где скачал не помню, но думаю, найдешь..
1)MySQL БИБЛИОТЕКА ПРОФЕССИОНАЛА, ЛЕОН АТКИНСОН (файл в pdf'е, написана очень доступно, легко и интересно читается, полно примеров, НО это про 3 версию мускула)
2)MySQL, Поль Дюбуа (djvu, немного тяжелее читать, но зато это про 4 версию..)
Про 5 версию нашел только одну книгу, и то только в интернет-магазине, называется "Самоучитель MySQL 5"
ссылка: http://www.softtime.ru/sql/?id_article=84

ну и конечно же справку по мускулу читать надо... там вполне нормальный поиск


29-01-2008 06:52
Арсений, большое спасибо!
Я все понял, извините за ламерские вопросы, буду учить матчасть.


29-01-2008 06:48
ПРОЦЕДУРЫ НЕ ВОЗВРАЩАЮТ НИЧЕГО!
можно использовать выходные параметры, для того чтобы например указать что произошло: вставилась строка, или уже существовала строка с таким кодом и была обновлена, или не была обновлена..
Считать выходной параметр можно так:
Например, вызвали процедуру, указав ей переменную для выходного параметра

CALL proc_name(@variable)



Тогда чтобы узнать значение переменной, вызовем

SELECT @variable;



29-01-2008 06:39
ХП:
CREATE PROCEDURE `SelBook`(in id varchar(100))
BEGIN
  Drop table if exists mydb_test.TempBook;
  Create temporary table if not exists mydb_test.TempBook Select * from mydb_test.Book where `pid`=id;
END

Вызов:
MySQL.Query('CALL SelBook('+ GroupData.id+')');
query_result := MySQL.Query('select * from `TempBook` where `pid`=' + GroupData.id);

Если есть способ более простой и быстрый, прошу сообщить.
Заранее благодарю!


хм.. по моему тебе нужна не процедура, а VIEW. Эт типа запроса, хранимого в СУБД..
Создается "CREATE VIEW `view_name` AS SELECT * FROM table_name;"
Запускается "SELECT * FROM view_name"

стореды нужны, как я понял для того, чтобы например добавлять информацию в базу или изменять ее..
вот например у меня такая процедура:
(для пополнения/изменения списка товаров на складе)


CREATE DEFINER=`root`@`localhost` PROCEDURE `goods_add`(ID smallint, nm char(45), unit_snm char(3))
BEGIN
IF ID IS NOT NULL THEN
INSERT INTO goods(IDgoods,name,IDunit,`count`) VALUES (ID,nm,(SELECT IDunit FROM unit WHERE shortname=unit_snm),0)
ON DUPLICATE KEY UPDATE name=nm, IDgoods=ID;
ELSE
INSERT INTO goods(name,IDunit,`count`) VALUES (nm,(SELECT IDunit FROM unit WHERE shortname=unit_snm),0);
END IF;
END



ПРОЦЕДУРЫ НЕ ВОЗВРАЩАЮТ НИЧЕГО!
для этого, на крайняк, есть функции:


(функция проверяет совместимость единиц измерения. Например килограмм и грамм совместимы- обе весовые, возвратит 1, а если разные типы, то значит несовместимы, следовательно 0)
CREATE DEFINER=`root`@`localhost` FUNCTION `unit_type_equal`(IDunit1 SMALLINT, IDunit2 SMALLINT) RETURNS tinyint(1)
BEGIN
RETURN (SELECT IDunittype FROM unit WHERE IDunit=IDunit1)=(SELECT IDunittype FROM unit WHERE IDunit=IDunit2);
END



29-01-2008 05:42
Большое спасибо!
Теперь я понял - почему у меня не получалось...


29-01-2008 05:18
сообщение от автора материала
Извините за назойливость, но у меня к вам еще один вопросик:
Что-то у меня не получается вытящить картинку с Bloba.

1. ВНИМАТЕЛЬНО смотрим какие блобы сколько информации вмещают.
2. Внимательно смотрим обсуждение ниже и делаем соответствующие изменения в коде. (Номера вопроса/ответа я только что давал Арсению, но всё равно прочитайте всё чтобы не спрашивать где что менять).
3.

var
  tempStr: string;
  stream: TMemoryStream;
begin
  tempStr := query_result.ValueByName['image']; //предположим ваш blob называется image
  stream := TMemoryStream.Create;
  try
    stream.Write(Pointer(tempStr)^, Length(tempStr));
    stream.Position := 0; // не забывайте обнулять позицию stream
    //отобразим в TImage
    Image1.Picture.Bitmap := TBitmap.Create;
    Image1.Picture.Bitmap.LoadFromStream(stream);
    //сохраним на диске
    stream.Position:=0;
    stream.SaveToFile('c:\b.bmp');
  finally
    stream.free;
  end;
end;

 riff


29-01-2008 04:00
Автор пишет:
P.S. А чем твоя конструкция с ХП отличается от просто
query_result := MySQL.Query('select * from `book` where `pid`=' +  GroupData.id);

Извините, если ввел вас в недоумение. Просто забыл пояснить, что я хотел попробовать работу с ХП, а сточки зрения целесообразности, вы абсолютно правы, что в вашем коде эта(ХП)  лишний хвост.

Извините за назойливость, но у меня к вам еще один вопросик:
Что-то у меня не получается вытящить картинку с Bloba.
Если не трудно дайте примерчик.


28-01-2008 10:21
сообщение от автора материала
Serge: Если есть способ более простой и быстрый, прошу сообщить. Не совсем понятно что вообще-то хочешь в итоге получить и что именно хочешь упростить. Компонент хранимые процедуры, можно сказать поддерживает - т.к. хп выполняются точно также посылкой правильной sql команды. Если возвращение данных не предпологается, то вместо MySQL.Query лучше вызывать MySQL.execSQL. Скорость зависит от твоих знаний sql, но, извини, т.к. к работе компонента этот вопрос не имеет отношения, то лучше его(вопрос) точней сформулировать и задать в форуме.

P.S. А чем твоя конструкция с ХП отличается от просто

query_result := MySQL.Query('select * from `book` where `pid`=' + GroupData.id);

я чего-то не догнал...
 riff


28-01-2008 09:41
По моему выкрутился, т.е. если применять ХП, то последовательность должна быть такая:

ХП:
CREATE PROCEDURE `SelBook`(in id varchar(100))
BEGIN
  Drop table if exists mydb_test.TempBook;
  Create temporary table if not exists mydb_test.TempBook Select * from mydb_test.Book where `pid`=id;
END

Вызов:
MySQL.Query('CALL SelBook('+ GroupData.id+')');
query_result := MySQL.Query('select * from `TempBook` where `pid`=' + GroupData.id);

Если есть способ более простой и быстрый, прошу сообщить.
Заранее благодарю!


28-01-2008 08:59
Спасибо за ответ!
Создана ХП:
CREATE PROCEDURE `SelBook`(In id varchar(100))
BEGIN
   Select * from book where `pid`=id;
END

вызываю:
query_result := MySQL.Query('CALL SelBook('+ GroupData.id+')');

Выдает:
Ошибка - процедура SelBook не может возвратить результат

Подскажите, пожалуйста, что я не так... делаю?


28-01-2008 08:39
Если процедура создана, то запросом "CALL proc_name(par_in, @par_out);" (proc_name -имя процедуры,par_in- входной параметр, @par_out- переменная, выходной параметр), по моему так..


28-01-2008 08:01
Все хорошо работает, спасибо автору!
Я еще, можно сказать, учусь работать в Delphi, поэтому вопросик:
Подскажите, пожалуйста, как, используя эти инструменты, можно вызвать хранимую процедуру с ВХОДНЫМИ и ВЫХОДНЫМИ параметрами? Было бы супер, если с примерчиком.


26-01-2008 05:36
сообщение от автора материала
ЕСЛИ при выпонении на одном из этапов execsql вернул false наверно неточно выразился, если на каком-то этапе ты решил не сохранять сделанные изменения, то откатить. Так  будет точнее.
 riff


26-01-2008 05:30
сообщение от автора материала
Подскажите, поддерживает ли он транзакции? Вобщем мне нечего добавить к ответу Арсения. Просто посмотри в мануале какой тип базы что может. Как это осуществить в программе? Посылаешь sql команды (MySql.ExecSql('...')) начать транзакцию, что-то выполнить, ЕСЛИ при выпонении на одном из этапов execsql вернул false откатить тразакцию, иначе подтвердить.
 riff


26-01-2008 02:31
По моему, трунзакции поддерживает не компонент, а сервер MySQL
Компонент просто передает SQL-код северу, и если нужно, возвращает результат..
MySQL не поддерживает транзакции для стандартного типа таблиц (MyISAM),
так же для него не поддерживается ссылочная целостность.
Зато производительность обработки запросов к этому типу таблиц очень высока.

А вот для раширенного типа таблиц (например InnoDB) поддерживается и то и то.(конечно в ущерб производительности)
Как использовать транзакции?
Для начала почитай мануал к серверу.. я сам не использовал пока, но по моему с помощью комманд "SET TRANSACTION"(?) "BEGIN" "COMMIT" "ROLLBACK"


26-01-2008 00:56
Добрый день.
Посмотрел на компонент с примером. Легко, понятно.
Подскажите, поддерживает ли он транзакции? Как это осуществить в программе?


25-01-2008 09:08
сообщение от автора материала
с блобами работать возможно?
Кажется да, "кажктся" потому что на 100% не тестировал.
Посмотри:
* Вопрос: 20-11-2007 08:55
* Ответ: 20-11-2007 11:47
 riff


25-01-2008 08:57
Спасибо большое! Вы мне очень помогли!
Последний вопрос:с блобами работать возможно? :)


25-01-2008 08:55
сообщение от автора материала
может у меня старая версия компонент? Я пользуюсь той же версией что и на сайте. Единственное версию libmysql.dll взял из своей версии mysql, но проверил твой вопрос с той версией библиотеки что на сайте - работает.
 riff


25-01-2008 08:47
сообщение от автора материала
Ну вот и нашли твою ошибку... Должно быть MySQL: IMySQL;
MySQL - это интерфейсная ссылка. А ты, объявив её как объект, выходя из процедуры, где её инициализируешь, просто напросто теряешь. И соответственно никаких mysql.free в конце работы не надо. И то что Один раз у тебя получается сделать селект - это чистая случайность.

Объяви как MySQL: IMySQL; и радуйся жизни. :)
 riff


25-01-2008 08:40
ах да, простите.. :)

var mysql:TMysql;



25-01-2008 08:21
сообщение от автора материала

mysql:=TMysql.create(); по моему так...

это не объявление, а инициялизация :) а вот
var
  I: Integer;
это объявление.
 riff


25-01-2008 08:18
mysql:=TMysql.create(); по моему так...


25-01-2008 06:33
сообщение от автора материала
Блин(это я себе. такую же, скорей всего ошибку допустил), Арсений, у тебя как переменная MySQL объявлена?
 riff


25-01-2008 06:23
сообщение от автора материала
Арсений:
Чёто и у меня глюки полезли... сейчас, подожди, разберусь.
 riff


25-01-2008 05:31
кажись забыл строку выделенную жирным. она должна быть до обращения к таблицам или так "select * from db.t1"

У меня есть кнопка OpenDB:

procedure TForm1.Button5Click(Sender: TObject);
begin
MySQL.Database := 'DB';
CheckBox4.Checked:=MySQL.Database = 'DB';
    if MySQL.Database <> 'DB' then
    begin
  Caption := Format('#%d - %s', [MySQL.ErrorCode, MySQL.ErrorMessage]);
      Exit;
   end;
    MySQL.ExecSQL('SET CHARSET cp1251');
end;



Я не могу понять, почему у меня после первого же запроса на селект соединение с сервером разрывается?
с другими запросами все в порядке. (правда, апдейт я не проверял еще)
может у меня старая версия компонент?


25-01-2008 03:55
сообщение от автора материала
Василий Болгар:
Действительно. Назовём его недочётом т.к. в коде используется переменная FHost а не property Host, так что на внутреннюю работу это не влияет.
 riff


25-01-2008 03:51
сообщение от автора материала
Арсений:
В твоём коде ничего не менял. Сделал следующее:

procedure TForm2.FormCreate(Sender: TObject);
begin
  MySQL := TMySQL.Create;
  MySQL.Host := 'localhost';
  MySQL.Port := 3306;
  MySQL.User := '...';
  MySQL.Password := '...';
  checkbox1.Checked:=MySQL.Connect;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  checkbox2.Checked:=MySQL.ExecSQL('CREATE DATABASE как у тебя');

  mysql.Database := 'DB';

  checkbox5.Checked:=
    MySQL.ExecSQL('CREATE TABLE `T1` как у тебя');
  checkbox6.Checked:=
    MySQL.ExecSQL('CREATE TABLE `T2` как у тебя');
end;

procedure TForm2.Button2Click(Sender: TObject);
var
  s:string;
  i: Integer;
begin
  s:='INSERT INTO T1 как у тебя';
  for i:=1 to memo1.Lines.Count-1 do
    s:=s+',('''+memo1.Lines[i]+''')';
  CheckBox7.Checked:=MySQL.ExecSQL(s);

  s:='INSERT INTO T2 как у тебя';
  for i:=1 to memo2.Lines.Count-1 do
    s:=s+',('''+memo2.Lines[i]+''',1)';
  for i:=0 to memo3.Lines.Count-1 do
    s:=s+',('''+memo3.Lines[i]+''',2)';
  CheckBox8.Checked:=MySQL.ExecSQL(s);
end;

procedure TForm2.Button3Click(Sender: TObject);
var
  q: IMySQLQuery;
  i:integer;
begin
  q:=mysql.Query('SELECT * FROM T1');
  //далее как у тебя
end;

procedure TForm2.Button4Click(Sender: TObject);
var
  q: IMySQLQuery;
  i:integer;
begin
  q:=mysql.Query('SELECT * FROM T2');
  //далее как у тебя
end;



Нажимаю кнопки подряд - всё Ok.
та кажись забыл строку выделенную жирным. она должна быть до обращения к таблицам или так "select * from db.t1"
 riff


24-01-2008 05:19
Нашел! Ошибка здесь, в "MySqlClasses.pas".


function TMySQL.GetDatabase: string;
begin
  Result := FDatabase;
end;

function TMySQL.GetHost: string;
begin
  Result := FDatabase; {!!!!!!!!!!!!!!!!!!!1}
end;



24-01-2008 05:13
Я не часто в Инете сижу, но сюда захожу. Пользуюсь компонентом mysql. Спасибо!
Я не знаю, но в скачанной мной версии (месяца 2 назад скачал) есь такая ошибка


function Блаблабла.GetHost:String;
begin
  Result:=FDatabase; {!!! не FHost, а именно FDatabase !!!}
end;


Описал не точно, а на память, сейчас просто я не дома.


24-01-2008 04:59
простите за отдельные посты- в один все не влезло(((


24-01-2008 04:58
Я создаю дочернюю таблицу:

  checkbox6.Checked:=
MySQL.ExecSQL('CREATE TABLE `T2` ('+
                           'id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, ' +
                           'text VARCHAR( 25 ) NOT NULL, ' +
                           'idT1 SMALLINT UNSIGNED NOT NULL, ' +
                           'FOREIGN KEY (idT1) REFERENCES T1(id) '+
                           'ON DELETE CASCADE '+
                           'ON UPDATE CASCADE '+
                                 ') ENGINE = InnoDB CHARACTER SET cp1251 COLLATE cp1251_general_ci');



Я заполняю родительскую таблицу из Мемо:

s:='INSERT INTO T1 (name) VALUES ('''+memo1.Lines[0]+''')';
for i:=1 to memo1.Lines.Count-1 do
s:=s+',('''+memo1.Lines[i]+''')';
CheckBox7.Checked:=MySQL.ExecSQL(s);



Я заполняю дочернюю из двух мемо(в первом мемо всего две записи):

s:='INSERT INTO T2 (text,idT1) VALUES ('''+memo2.Lines[0]+''',1)';
for i:=1 to memo2.Lines.Count-1 do
s:=s+',('''+memo2.Lines[i]+''',1)';
for i:=0 to memo3.Lines.Count-1 do
s:=s+',('''+memo3.Lines[i]+''',2)';
CheckBox8.Checked:=MySQL.ExecSQL(s);


____________________________________________

до сих пор все работает нормально, без проблем
Но вот после всех этих стараний я решил сделать выборки из таблиц.
Сделал два идентичных запроса:
К родительской:

var
q: IMySQLQuery;
i:integer;
begin
q:=mysql.Query('SELECT * FROM T1');
if q=nil then
   Caption := Format('%d - %s', [MySQL.ErrorCode, MySQL.ErrorMessage])
   else
begin
sg.ColCount:=q.FieldCount;
sg.RowCount:=q.RecordCount;
while q.FetchRow() do
begin
for i:=0 to q.FieldCount-1 do
sg.Cells[i,q.RecNo]:=q.Values[i];
end;
end;
end;



И к дочерней:

var
q: IMySQLQuery;
i:integer;
begin
q:=mysql.Query('SELECT * FROM T2');
if q=nil then
   Caption := Format('%d - %s', [MySQL.ErrorCode, MySQL.ErrorMessage])
   else
begin
sg.ColCount:=q.FieldCount;
sg.RowCount:=q.RecordCount;
while q.FetchRow() do
begin
for i:=0 to q.FieldCount-1 do
sg.Cells[i,q.RecNo]:=q.Values[i];
end;
end;
end;



Это все была призказка,
теперь, собственно, сама проблема:
Когда я делаю запрос на выборку(любой из двух), все проходит нормально, stringgrid заполняется информацией.
Но после этого ни один запрос не работает:
если я сделаю второй запрос на выборку, то он возвращает NIL с неизвестной ошибкой и 8-значным кодом...
если я попробую отправить INSERT-запрос, вылетает Access Violation..
работает только Disconnect
Но после повторного коннекта и открытия бд запрос на выборку тоже вылетает в Access Violation...


Что я сделал не так? Любые советы(не только по заданному вопросу, но и вцелом по процитированному коду) будут приняты с преввеликою благодарностию)))


24-01-2008 04:57
Здраствуйте, уважаемые!
Проблема такова:
Я постарался сделать все почти как в предложенном примере(за исключением того, что я выбрал движок иннодб и сделал связь с проверкой целостности)
И у меня почти :( получилось:
Я соединяюсь с сервером:

  MySQL.Host := 'localhost';
  MySQL.Port := 3306;
  MySQL.User := '';
  MySQL.Password := '';
  checkbox1.Checked:=MySQL.Connect;



Я создаю базу:

checkbox2.Checked:=MySQL.ExecSQL('CREATE DATABASE `DB` DEFAULT CHARACTER SET CP1251');



Я создаю родительскую таблицу:

  checkbox5.Checked:=
MySQL.ExecSQL('CREATE TABLE `T1` ('+
                           '`id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, ' +
                           '`name` VARCHAR( 25 ) NOT NULL' +
                           ') ENGINE = INNODB CHARACTER SET cp1251 COLLATE cp1251_general_ci');





20-11-2007 11:47
сообщение от автора материала
Или вот так:

function mysql_fetch_lengths(result: pmysql_res): Pointer; stdcall;
function mysql_fetch_lengths(result: pmysql_res): Pointer; stdcall; external libmySQL;


function TMySQLQuery.GetValues(FieldNo: Integer): string;
var
  lengths: Pointer;
  length: Integer;
begin
  if FRow <> nil then
  begin
    Lengths := mysql_fetch_lengths(FRes);
    if Lengths <> nil then
    begin
      length := PCardinal(LongInt(Lengths) + FieldNo * SizeOf(Cardinal))^;
      SetLength(Result, length);
      Move(FRow[FieldNo]^, Pointer(Result)^, length);
    end else
      Result := '';
  end else
    Result := '';
end;

 riff


20-11-2007 11:34
сообщение от автора материала
А, нет не надо изменять описания функций - это я нитуда посмотрел. и соответственно
var
  Fl: LongWord; в функции GetValues
 riff


20-11-2007 11:29
сообщение от автора материала
Попробуй
1. Исправь соответствующие описания функций:

function mysql_fetch_lengths(result: pmysql_res): PLongWord; stdcall;
function mysql_fetch_lengths(result: pmysql_res): PLongWord; stdcall; external libmySQL;



2. замени

function TMySQLQuery.GetValues(FieldNo: Integer): string;
begin
  if FRow <> nil then
    Result := StrPas(FRow[FieldNo]);
end;


на

function TMySQLQuery.GetValues(FieldNo: Integer): string;
type
  TCA = array of LongWord;
var
  Fl: PLongWord;
begin
  if FRow <> nil then
  begin
    Fl := mysql_fetch_lengths(FRes);
    SetLength(Result, TCA(Fl)[FieldNo]);
    Move(FRow[FieldNo]^, Pointer(Result)^, TCA(Fl)[FieldNo]);
  end;
end;


Вся информация будет возвращаться в результирующей строке. Это я на 100% не проверял, сделал на скорую руку.
 riff


20-11-2007 08:55
Господа, А как с помощью этого компонента работать с БЛОБ полями?
Сообщение не подписано


06-10-2007 03:49
сообщение от автора материала
MySQL.ExecSQL('SET CHARSET cp1251'); видимо надо(правильнее) писать после того как подключился к какой-либо базе, а не просто к mysql. т.е. ещё раз
либо
MySQL.Host :=
MySQL.Port :=
MySQL.User :=
MySQL.Password :=
MySQL.Database :=
if MySQL.Connect then
begin
  MySQL.ExecSQL('SET CHARSET cp1251');
end;


либо
MySQL.Host :=
MySQL.Port :=
MySQL.User :=
MySQL.Password :=
MySQL.Connect;

MySQL.Database :=
MySQL.ExecSQL('SET CHARSET cp1251');

 riff


04-10-2007 08:22
сообщение от автора материала
Sairex: кстати правда чутог пришлось подправить вообще-то хорошо бы указать места расположения ошибок.
А чуть ранее, до того как увидел ваше сообщение, я отправил обновление MySql. Так что если изменения существенные, то придётся ещё раз обновить, а если мелочь пузатая, то в комментариях им самое место.
 riff


04-10-2007 06:25
Молодец афтар-жжет. Компоненты удобные, кстати правда чутог пришлось подправить а так все куль!


27-08-2007 05:42
Спасибо удобные компоненты, а как мне реализовать доступ к mysql из других локальных машин?


21-06-2007 21:15
Спасибо за компонент, пока все понятно. Это то, что я уже давно искал, а сам не решался сделать.

Большой респект и уважуха.


25-05-2007 06:17
сообщение от автора материала
Спасибо, теперь буду знать. До этого момента не было необходимости знать были ли найдены записи для update (ну т.е. заранее знал что обновляю), поэтому не обращал внимания. Сейчас понадобилось обновить nное кол-во записей, если нет - добавить, хотел положиться на AffectedRows.
 riff


25-05-2007 03:25
А число найденных записей и число затронутых записей может не совпадать?
Ну да, например при UPDATE который не меняет содержимое какой-то записи (что было, то и записали), в этом случае с CLIENT_FOUND_ROWS вернётся общее число проанализированных записей, а без число реально изменённых, то есть тех в которых изменилось значение хотя бы одного поля.
Видимо из-за непонимания этого вы и удивляетесь, что  иногда возвращает кол-во, а иногда нет. Только, если не ошибаюсь, в какой-то из версий был баг в этом механизме.
 DRON


23-05-2007 23:58
сообщение от автора материала
А число найденных записей и число затронутых записей может не совпадать? Если можно, какой-нибудь примерчик.
А без этого флага, как уже сказал, в тестовом примере возвращает кол-во, а подобный же update в другой программе не возвращает... Может у кого-то по этому поводу будут советы?
 riff


23-05-2007 12:38
При включении этого флажка будет возвращаться несколько не то:
     `CLIENT_FOUND_ROWS'  Return the number of found (matched) rows,      
                          not the number of affected rows.
 DRON


23-05-2007 07:44
сообщение от автора материала
Что бы функция AffectedRows возвращала количество записей затронутых коммандами "update", "delete", "insert" - найдите в юните MySqlClasses строку:
FConnection := mysql_real_connect(FMySQL, PChar(FHost), PChar(FUser),
  PChar(FPassword), PChar(FDatabase), FPort, nil, 0);
и замените 0(ноль) на 2(два). Иначе она иногда возвращает кол-во, а иногда нет.
 riff


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Жили у бабуси два веселых гуся. Один белый, другой КАКОЙ?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.

Оценка содержания
 
Содержит полезные и(или) интересные сведения
 
Ничего особенно нового и интересного
 
Написано неверно (обязательно укажите почему)


Оценка стиля изложения
 
Все понятно, материал читается легко
 
Есть неясности в изложении
 
Непонятно написано, трудно читается

Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования