Работа с PostgreSQL. У кого есть элементтарный пример?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение Pisklov_A » 11.03.2008 16:00:25

Приветствую вас!

Подскажите, может у кого то есть готовый пример кода, с подключением к PostgreSQL и элементарной работой с БД (допустим запрос создания пользователя).
Pisklov_A
новенький
 
Сообщения: 26
Зарегистрирован: 20.10.2006 16:09:08

Сообщение NXP » 11.03.2008 19:48:49

Вот кусок кодов консольного сервера , работающего с Postgres

Код: Выделить всё
uses Classes, Crt, SysUtils, lNet, SQLDB, PQConnection,

  TServer = class (TThread)                     {* сервер обмена файлами *}
  private
    SQLQuery:       TSQLQuery;                     {коммандный процессор SQL}
    SQLTransaction: TSQLTransaction;               {координатор транзакций}
    PQConnection:   TPQConnection;                 {интерфейс PostgreSQL сервера}
  public
    constructor Create(Params: pSRVParamRec);
    destructor Destroy; override;
  protected
    procedure Execute; override;
  end;


Нало всего с...

Код: Выделить всё
constructor TServer.Create(Params: pSRVParamRec);
begin

  SQLQuery:=          TSQLQuery.Create(nil);
  SQLTransaction:=    TSQLTransaction.Create(nil);
  PQConnection:=      TPQConnection.Create(nil);
 

  inherited Create(false);
end;

destructor TServer.Destroy;
begin
  PQConnection.Close;
  SQLQuery.Free;
  SQLTransaction.Free;
  PQConnection.Free;
  inherited Destroy;
end;


инициализация...

Код: Выделить всё
procedure TServer.Execute;
begin

  try                                              {подключение к SQL}
    PQConnection.HostName:=     Param^.SQL_Server;
    PQConnection.UserName:=     Param^.SQL_User;
    PQConnection.Password:=     Param^.SQL_Password;
    PQConnection.DatabaseName:= Param^.SQL_DateBase;
    PQConnection.Open;
    SQLQuery.DataBase:=        PQConnection;
    SQLQuery.Transaction:=     SQLTransaction;
    SQLTransaction.DataBase:=  PQConnection;
    PQConnection.Transaction:= SQLTransaction;
  except
    on E: Exception do begin
      LogMsg:= '@Execute: ' + E.Message;
      Log(LogMsg);
      Param^.Critical_Log(LogMsg);
      Terminate;
    end;
  end;

+++


end;


Вот собственно использование...

Код: Выделить всё
procedure TServer.SrvReceive(aSocket: TLSocket);


  function UserAuth(Rec: pSocketRec): boolean; {SQL запрос для проверки user/pass}
  var Count: integer = 0;
      SQL_File: TStringList;
  begin
    Result:= false;
    if (Rec^.User_Code < 1) or                  {Преподавательский состав ID < 0}
      (Length(Rec^.User_Password) < 1) then exit(false); {пароль не может быть пустым}
    try
      SQL_File:= TStringList.Create;
      SQL_File.LoadFromFile(Param^.SQL_Path + DirectorySeparator + 'auth_user.sql');
      SQLQuery.SQL.Text:= SQL_File.Text;
      SQL_File.Free;
      SQLQuery.Params.ParamByName('SI_USRCOD').Value:=Rec^.User_Code;
      SQLQuery.Params.ParamByName('SI_PASS').Value:=Rec^.User_Password;
      SQLQuery.Open;
      while (not SQLQuery.EOF) do begin
        SQLQuery.Next;
        inc(count);
      end;
      SQLQuery.ClearFields;
      SQLQuery.Close;
      if (Count = 1) then exit(True) else exit(false);
    except
      on E: Exception do begin
             +++
      end;
    end;
  end;

begin

+++

        if not UserAuth(Client) then begin ...

+++

end;



Содержимое файла auth_user.sql:

Код: Выделить всё
SELECT * FROM users WHERE usr_id = :SI_USRCOD AND passwd = :SI_PASS AND blocked = FALSE



Учить SQL можно в PGAdmin
Нагляднее примера нет, т.к еще не доделал (
еще потребуются эти либы:
comerr32.dll
krb5_32.dll
libeay32.dll
libiconv-2.dll
libintl-2.dll
libpq.dll
ssleay32.dll
Аватара пользователя
NXP
постоялец
 
Сообщения: 187
Зарегистрирован: 02.01.2008 16:11:56
Откуда: Воронеж

Сообщение Pisklov_A » 12.03.2008 10:16:43

Благодарю вас.
Pisklov_A
новенький
 
Сообщения: 26
Зарегистрирован: 20.10.2006 16:09:08

Сообщение Zorro » 03.04.2008 07:30:28

У меня вопрос. использую lazarus 0.9.25 fps 2.2.1 + PostgreeSQL 8.3 (WinXP) / Связка PQConnection -> SQLTransaction->SQLQuery /
при запросе на выборку тоесть Select // все работает..
НО при запросе Insert Into или Update выскакивает ошибка
"Cannot open non-select statement " В чем может быть проблема?

для наглядности приведу элементарный пример с сохранением синтаксиса. " Insert into "User_name" (id, "name") Values (8, 'Vasia'); "
Заранее благодарю.

в одном из постов на форуме видел что при использовании Inser Into Update или SET нужно использовать не SQLQuery.Open а ExecSQL... пробовал.. ошибка не появляется но и в таблицу ничего не добавляется
Zorro
незнакомец
 
Сообщения: 1
Зарегистрирован: 03.04.2008 07:13:59

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение sadavod » 27.12.2009 17:47:42

Присоединяюсь к последнему сказанному, хоть двух годовалой давности сообщение
sadavod
новенький
 
Сообщения: 18
Зарегистрирован: 27.12.2009 14:30:29

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение Logo » 27.12.2009 19:08:42

Выложите, пожалуйста, свой пример программы. Все работает прекрасно за исключением кодировки UTF8, если база в этой кодировке, то будет обрезать кириллические строки, но есть патч для FPC устраняющий эту проблему.
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re:

Сообщение sadavod » 27.12.2009 21:54:10

Zorro писал(а):в одном из постов на форуме видел что при использовании Inser Into Update или SET нужно использовать не SQLQuery.Open а ExecSQL... пробовал.. ошибка не появляется но и в таблицу ничего не добавляется
до глубины души согласен.

Запрос - INSERT INTO s1.t1(pole)VALUES (99);
все как бы просто, не правдали?

как программим (способ 1 - ошибка запроса на стадии SQLQuery1.SQL.Add)
Код: Выделить всё
PQConnection1.Connected:=true;
   except
      .............
   end;
   try
      SQLTransaction1.Active:=true;
   except
      .................
    end;
   try
           SQLQuery1.Close;
           SQLQuery1.SQL.Clear;
           SQLQuery1.Insert;
           SQLQuery1.SQL.Add('INSERT INTO s1.t1(pole)VALUES (99);');
           SQLQuery1.Open;
   except
     .................
   end;


как программим (способ 2 - кто нибудь есть дома? ну или что то делается но результата не видно, но делается точно так как нельзя создать 2-ды таблицу с одинаковым именем)
Код: Выделить всё
     
PQConnection1.Connected:=true;
   except
      .............
   end;
   try
      SQLTransaction1.Active:=true;
   except
      .................
    end;
   try
      SQLQuery1.Close;
      SQLQuery1.SQL.Clear;
      SQLQuery1.SQL.Add('INSERT INTO s1.t1(pole)VALUES (99);');
      SQLQuery1.ExecSQL;
   except
     .................
   end;
sadavod
новенький
 
Сообщения: 18
Зарегистрирован: 27.12.2009 14:30:29

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение Logo » 28.12.2009 04:11:06

SQLQuery1.Open или SQLQuery1.Active := True применяется только для получения данных при использовании SELECT. Остальные операции CREATE, INSERT, DELETE, UPDATE - выполняются SQLQuery1.ExecSQL;

SQLQuery1.SQL.Add('INSERT INTO s1.t1(pole)VALUES (99);'); - перед VALUES должен быть обязательно пробел. "pole" какого типа? Если строка, то 99 нужно взять в одинарные кавычки.

В принципе, PQConnection неплохо сообщает об ошибках, я не знаю, как Вы обрабатываете ошибки на except, если никак, то лучше уберите кострукции try except, будет яснее картина с ошибками.

Добавлено спустя 14 минут 8 секунд:
Вот реальный пример, скопировал из работающей программы:
Код: Выделить всё
procedure TfrmTools.DoSaveIPsToDB(v_contype, v_class, v_net, v_mask, v_gateway,
                       v_broadcast, v_state, v_name: String);
begin
  try
    sqlToolsActions.SQL.Text :=
    'INSERT INTO localip('
       +'lip_contype, lip_class, lip_net, lip_mask, lip_gateway, '
       +'lip_broadcast, lip_state, lip_name) '
       +'VALUES ('
       +v_contype+', '  //lip_contype
       +v_class +', ' //lip_class
       +v_net +', ' //lip_net
       +v_mask +', ' //lip_mask

       +v_gateway +', ' //lip_gateway
       +v_broadcast+', ' //lip_broadcast

       +v_state+', '  //lip_state
       +v_name //lip_name
       +');';
    sqlToolsActions.ExecSQL;

  except
   //error
  end;
end;

Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение Climber » 28.12.2009 13:02:06

sadavod
В способе №1 надо делать немного иначе:
Код: Выделить всё
try
           SQLQuery1.SQL.Text:='select * from mytable where <какое-нибудь условие, возвращающее заведомо ноль строк - чтобы базу не грузить почем зря>';
           SQLQuery1.Open;
           SQLQuery1.Insert;
           SQLQuery1.FieldByName('my_integer_field').AsInteger:=123;
           SQLQuery1.FieldByName('my_datetime_field').AsDateTime:=now-2; // типа позавчера
           SQLQuery1.FieldByName('my_string_field').AsString:='Строка какая-нибудь';
           SQLQuery1.Post;
   except
     .................
   end;
C update тоже самое, только самый первый запрос должен возвращать редактируемую строку.
А вообще непонятно, какие могут быть проблемы, связка Lazarus + zeos +PostgreSQL работала еще год назад как швейцарские часы. 8)

Добавлено спустя 4 минуты 56 секунд:
Хочу так же обратить внимание на преимущества связки Insert + Post: если надо вставить строку, содержащую апостроф, то его надо продублировать, так как это управляющий символ языка SQL. Для этого надо использовать функцию QuotedStr. Один раз ошибешься - получишь exception. В случае выполнения команды
Код: Выделить всё
SQLQuery1.FieldByName('my_string_field').AsString:='Строка какая-нибудь';
компонент Query делает это самостоятельно, так что никаких проблем никогда не возникнет.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение sadavod » 28.12.2009 16:52:33

Спасибо за ответы еще не тестировал как они работают (дома проверю отпишусь), не понятен мне это момент покамест

<какое-нибудь условие, возвращающее заведомо ноль строк

зачем это?
sadavod
новенький
 
Сообщения: 18
Зарегистрирован: 27.12.2009 14:30:29

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение Climber » 28.12.2009 17:21:32

sadavod писал(а):Спасибо за ответы еще не тестировал как они работают (дома проверю отпишусь), не понятен мне это момент покамест

<какое-нибудь условие, возвращающее заведомо ноль строк

зачем это?

Ну как. Чтобы выполнить Query.Insert или Query.Update, нужно, чтобы датасет был открыт (т. е. сначала выполнить Query.Open). Если редактируешь - то понятно, открываем датасет с редактируемой строкой. А если открываешь датасет для вставки новой строки? То пофиг, что там будет в датасете. Я делаю что-нибудь ненапряжное для сервера. Но это для случая, когда в момент выполнения Query.Open известно, что будет дальше - Insert или Update. Если заранее незвестно, то просто открываешь то, что надо в данный момент.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение sadavod » 28.12.2009 20:14:19

Спасибо ребята, всё заработало
sadavod
новенький
 
Сообщения: 18
Зарегистрирован: 27.12.2009 14:30:29

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение dunin » 22.01.2010 23:51:01

Climber писал(а):sadavod
В способе №1 надо делать немного иначе:
...

Или так:
Код: Выделить всё
const
  sql001 = 'Неверно заданы параметры в процедуре';   
...
function InsSQL  (Base:tIBConnection; TableName: string; FieldsName: array of string; NewValues: array of variant; DoCommitRetaining: boolean = True): boolean;
  var iSQL: tSQLQuery;
      S: string; I: Integer;
begin
  if (Length(FieldsName) <> Length(NewValues))
    then begin
      raise Exception.Create(sql001+' InsSQL');
      exit;
    end;

  iSQL:= tSQLQuery.Create(Base);
  iSQL.DataBase:= Base;
  iSQL.Transaction:= Base.Transaction;
  iSQL.SQL.Clear; // ?????

  iSQL.SQL.Add('insert into '+TableName+' ');
  S:='';
  for I:= 0 to High(FieldsName)
    do S:= S + TableName+'.'+FieldsName[i]+',';
  SetLength(S, Length(S)-1);
  iSQL.SQL.Add('('+S+') values ');
  S:='';

  for I:= 0 to High(NewValues)
    do S := S+':'+IntToStr(i)+',';
  SetLength(S, Length(S)-1);
  iSQL.SQL.Add('('+S+')');

  for I:= 0 to High(NewValues)
    do iSQL.Params.ParamByName(inttostr(i)).Value:= NewValues[i];
  try
    iSQL.ExecSQL;
    if DoCommitRetaining then Base.Transaction.CommitRetaining;
  finally
    iSQL.Close; iSQL.Free;
    Base.Transaction.Active:=True;
  end;//finally
Result:= True;
end;

Создаем tSQLOuery, передаем значения сразу через параметры, освобождаем. Использую когда надо оперативно что-то куда-то подпихнуть. Пример для tIBConnection. Переделать не сложно. Для удаления и пр. есть схожие функции.
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение Nadin » 15.03.2010 13:26:59

Пожалуйста, дайте пример на Update. Там тоже надо через параметры передавать?
Nadin
новенький
 
Сообщения: 10
Зарегистрирован: 22.07.2009 11:58:59
Откуда: Красноярск

Re: Работа с PostgreSQL. У кого есть элементтарный пример?

Сообщение Climber » 15.03.2010 14:02:17

Update ничем не отличается от Insert. Все тоже самое.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 219

Рейтинг@Mail.ru