SQL запрос в SQLite - страница 2

 
prostotrader #:

Так как составить зарос, чтобы

1. если в таблице нет записей, то запись добавилась

2. если есть запись, то она обновилась новыми данными

Т.е. запись всегда должна быть одна, но с новыми данными

схему таблицы приведите - покажем где исправить.

(текст с CREATE TABLE....)

 
prostotrader:

Привет!

Есть база данных SQLite

Как составить запрос, чтобы приходящие данные переписывали первую строчку,  если она существует, и добавились, если ничего нет?

Т.е была бы всегда только одна строка.


При таком запросе - крэш

А так нельзя?

REPLACE INTO FORTS_название_таблицы ( replID, replRev , replAct , server_time ) VALUES ( '8327... ' , '8327... ' , '0', '08.12...' )

При этом replID должен быть уникальным ключом либо добавить ключ как номер строки (всегда задавать = 1), чтобы не искать значение поля replID.

 
Maxim Kuznetsov #:

схему таблицы приведите - покажем где исправить.

(текст с CREATE TABLE....)

Ну, если Вы считаете, что Вам это поможет, то пожалуйста

Создание таблицы

procedure TStorageForm.SetTblsDesc(var StrData: TStreamData);
var
  i, j: integer;
  ptable_desc: pcg_message_desc_t;
  Query: TFDQuery;
  Fields: pcg_field_desc_t;
  CmdStr: string;
begin
  ptable_desc:= StrData.Scheme^.messages;
  SetLength(StrData.Tables, StrData.Scheme^.num_messages);
  DBase.StartTransaction;                                   // start transaction
  try
    for i:= 0 to StrData.Scheme^.num_messages - 1 do
    begin
      StrData.Tables[i].tName:= string(ptable_desc^.name);  // Table name
      StrData.Tables[i].tIdx:= i;                           // Table index
      StrData.Tables[i].Rev:= 0;                            // Table  revision
      Fields:= ptable_desc^.Fields;
      CmdStr:= 'create table if not exists ' + StrData.sName + string(ptable_desc^.name) + ' (';
      for j:= 0 to ptable_desc^.num_fields - 1 do
      begin
        if(j = ptable_desc^.num_fields - 1) then
          CmdStr:= CmdStr + string(Fields.name) + ' ' +
            string(GetFieldType(string(ptable_desc^.name), Fields)) + ')' else
          CmdStr:= CmdStr + string(Fields.name) + ' ' +
            string(GetFieldType(string(ptable_desc^.name), Fields)) + ', ';
        Fields:= Fields^.next;
      end;
      Query:= TFDQuery.Create(self);                        // Create query
      Query.Connection:= DBase;                             // Set Connection
      try
        Query.SQL.Text:= CmdStr;
        Query.ExecSQL;
      finally
        Query.Free;
      end;
      ptable_desc:= ptable_desc^.next;
    end;
    DBase.Commit;
  except
    DBase.Rollback;
    raise;
  end;
end;

Обновление таблицы

procedure TStorageForm.UpdStrMsg(const msg: pcg_msg_streamdata_t;
                               const strData: TStreamData);
var
  sTable: pcg_message_desc_t;
  field: pcg_field_desc_t;
  Buff: PByteArray;
  FDQuery: TFDQuery;
  i: integer;
  FieldNames: string;
  Values: string;
  v: Variant;
begin                //TODO Check transaction in progress ?????????
  Buff:= PByteArray(msg^.data);                            // Get data Buffer
  if(StrData.Scheme^.scheme_type = CG_SCHEME_BINARY) then  // currently only CG_SCHEME_BINARY
  begin
   // RecAdd:= false;                                        // no record added
    sTable:= StrData.Scheme^.messages;
    for i:= 0 to StrData.Scheme^.num_messages - 1 do
    begin
      if(string(sTable.name) = string(msg^.msg_name)) then  // Set current table
        break;
      sTable:= sTable^.next;
    end;
    FieldNames:= '';
    Values:= '';
    Field:= sTable^.fields;
    while Field <> nil do
    begin
      if(FieldNames <> '') then
      begin
        FieldNames:= FieldNames + ',';
        Values:= Values + ',';
      end;
      FieldNames:= FieldNames + string(Field.name);
      Values:= Values + ':' + string(Field.name);
      Field:= Field^.next;
    end;
    FDQuery:= TFDQuery.Create(self);
    try
      FDQuery.Connection:= DBase;
      FDQuery.SQL.Text:= 'insert or replace into ' + strData.sName +
                         string(sTable.name) +  ' (' + FieldNames +
                         ') values (' + Values + ')';

      Field:= sTable^.fields;
      while Field <> nil do
      begin
        v:= GetFieldVar(field, buff);
        if((string(Field.name) = 'replAct') and (VarToInt64(v) > 0)) then exit;
        FDQuery.Params.ParamByName(string(Field.name)).Value:= v;
        Field:= Field^.next;
      end;
      FDQuery.ExecSQL();
    finally
      FDQuery.Free;
    end;
  end;
end;
 
Dmitriy Skub #:

А так нельзя?

REPLACE INTO FORTS_название_таблицы ( replID, replRev , replAct , server_time ) VALUES ( '8327... ' , '8327... ' , '0', '08.12...' )

При этом replID должен быть уникальным ключом либо добавить ключ как номер строки (всегда задавать = 1), чтобы не искать значение поля replID.

Сделал  create table FORTS_название_таблицы ( replID primary key,

Не помогло

 
prostotrader #:

Сделал  REPLACE INTO FORTS_название_таблицы ( replID primary key

Не помогло

А что значит не помогло? Это же спец команда для вставки (либо обновления, если  существует, строки).

Какая ошибка? Может синтаксис в метаквотовском отличается, как обычно, что-то изменили.

 
Dmitriy Skub #:
А что значит не помогло? Это же спец команда для вставки (либо обновления, если  существует, строки).

Сделал

create table if not exists FORTS_название_таблицы ( replID primary key, replRev , replAct , server_time ) VALUES ( '8327... ' , '8327... ' , '0', '08.12...' )

когда говорю

REPLACE INTO FORTS_название_таблицы ( replID, replRev , replAct , server_time ) VALUES ( '8327... ' , '8327... ' , '0', '08.12...' )

То строки добавляются (все)

Я использую SQLite

 
prostotrader #:

Сделал

create table if not exists FORTS_название_таблицы ( replID primary key, replRev , replAct , server_time ) VALUES ( '8327... ' , '8327... ' , '0', '08.12...' )

когда говорю

REPLACE INTO FORTS_название_таблицы ( replID, replRev , replAct , server_time ) VALUES ( '8327... ' , '8327... ' , '0', '08.12...' )

То строки добавляются (все)

Потому что у вас ReplID меняется.

Нет строки со значение ReplID как в запросе => создаётся новая строка
 
FORTS_название_таблицы - имеется в виду само название таблицы (просто лень писать все полностью), а не добавить к названию " FORTS_ ".
 
prostotrader #:

Сделал

create table if not exists FORTS_название_таблицы ( replID primary key, replRev , replAct , server_time ) VALUES ( '8327... ' , '8327... ' , '0', '08.12...' )

когда говорю

REPLACE INTO FORTS_название_таблицы ( replID, replRev , replAct , server_time ) VALUES ( '8327... ' , '8327... ' , '0', '08.12...' )

То строки добавляются (все)

Я использую SQLite

Так значение replID равно уже однажды добавленному в первую строку?
 
Sergey Gridnev #:
Потому что у вас ReplID меняется.

Я знаю, что меняется, как сделать?

Я вообще первый раз в жизни столкнулся с базой данных (лучше бы не делал этого, но нужда заставила)

Причина обращения: