2015-08-22 3 views
1

Что я делаю неправильно здесь, так как данные не вставлены в таблицу ARCHIVE , хотя в моей таблице T_Main есть 3 записи, в которых ACCOMPLISHED = True?Почему данные не вставлены?

База данных является Accuracer.

procedure TForm1.AdvGlowButton1Click(Sender: TObject); 
begin 
case cxRadioGroup1.ItemIndex of 
0: begin 
    if MessageDlg('Are you sure ?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then 
    begin Exit; 
    end else 
    Data_Module.T_MAIN.First; 
    while not Data_Module.T_MAIN.Eof do begin 
    Data_Module.INS_ARCH.Close; 
    Data_Module.INS_ARCH.SQL.Clear; 
    Data_Module.INS_ARCH.SQL.Text :='INSERT INTO ARCHIVE (T_ID,FOR_DATE,DONE_WHEN)' 
    + 'SELECT :a3,:a4,:a5 FROM T_MAIN WHERE ACCOMPLISHED =True '; 
    Data_Module.INS_ARCH.Params.ParamByName('a3').AsInteger := Data_Module.T_MAIN.FieldByName('T_ID').AsInteger; 
    Data_Module.INS_ARCH.Params.ParamByName('a4').AsDate := Data_Module.T_MAIN.FieldByName('FOR_DATE').AsDateTime; 
    Data_Module.INS_ARCH.Params.ParamByName('a5').AsDate := Data_Module.T_MAIN.FieldByName('DONE_WHEN').AsDateTime; 
    Data_Module.T_MAIN.Next; 
    Data_Module.INS_ARCH.ExecSQL; 
end; 
end; 
end; 
+0

Вы уверены, что ваш запрос на самом деле вернуть некоторые данные? Попробуйте выполнить только выбор в SQL DB, чтобы узнать, являются ли они данными возврата. Если он вернется, значит, ошибка указана в коде. Или, может быть, вам нужно какое-то утверждение commit в конце? –

+0

выберите T_ID, FOR_DATE, DONE_WHEN из T_ID, где ACCOMPLISHED = True; ---- возвращает правильные данные. – user763539

+0

Итак, если вы можете попробовать ручную вставку - может быть вставка не работает (например, ПК, Великобритания и т. Д.). Или проверьте, подключитесь ли вы к БД-подсказки (я сделал эту ошибку один раз). –

ответ

1

ваш запрос неправильно

Data_Module.INS_ARCH.SQL.Text :='INSERT ... SELECT :a3,:a4,:a5 FROM T_MAIN ....'; 

вы заполняете Params с данными не с реальными excisting полей базы данных.
пример:

Data_Module.INS_ARCH.SQL.Text :='INSERT ... SELECT 1000, 2015-08-22, 2015-08-01 FROM T_MAIN ....'; 
  • Вы уверенны или 2015-08-22 или 2015-08-01 действительно существующие поля базы данных?

EDIT из Вашего ответа:

Это, конечно, работает, потому что вы устанавливая действительные имена полей в вашем отборном заявлении.

SELECT T_ID,FOR_DATE,DONE_WHEN FROM T_MAIN 

С кода вашего выбора что-то вроде

SELECT 1000, 2015-08-22, 2015-08-01 FROM T_MAIN 
+1

Вы видели еще один шаг после того, что я увидел - я проскользнул прямо над частью запроса, скрытой в крайнем правом углу. –

0

, кажется, это работает:

procedure TForm1.AdvGlowButton1Click(Sender: TObject); 
begin 
case cxRadioGroup1.ItemIndex of 
0: begin 
    if MessageDlg('Are you sure ?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then 
    begin Exit; 
    end else begin 
    Data_Module.INS_ARCH.Close; 
    Data_Module.INS_ARCH.SQL.Clear; 
    Data_Module.INS_ARCH.SQL.Text :='INSERT INTO ARCHIVE (T_ID,FOR_DATE,DONE_WHEN) SELECT T_ID,FOR_DATE,DONE_WHEN FROM T_MAIN WHERE ACCOMPLISHED =True '; 
    Data_Module.INS_ARCH.ExecSQL; 
end; 
end; 
end; 
+0

Действительно, но я думаю, что было бы лучше упомянуть, что если архивирование происходит более одного раза, Sql нуждается в квалификации, чтобы не пытаться вставлять строки, которые уже находятся в ARCHIVE в результате предыдущего выполнения. Если они не нуждаются в обновлении, конечно. – MartynA

+1

Это даже не похоже, что он скомпилируется. Когда вы говорите 'end else', не следует ли« end else begin »? То же самое касается вашего вопроса. Это ваш реальный реальный код? –

+0

MartynA - там не может быть дубликатов в архиве, потому что записи удаляются из T_main, как только они вставлены. И они уникальны. Джерри, ты прав, конечно. Опечатка. – user763539

1

Вы не должны использовать параметры для имен полей. Это не для этого. Параметры предназначены для фактических значений данных. Обратите внимание на этот другой вопрос/ответ: How to use ADO Query Parameters to specify table and field names? Ваша настоящая проблема, хотя, как объясняется в ответе moskito-x, заключается в том, что вы передаете значения данных, как если бы они были именами полей.

На стороне примечания, есть другие вещи, которые не соответствуют вашему фрагменту кода. Вот моя попытка, по крайней мере, очистить его для вас, чтобы лучше читать:

procedure TForm1.AdvGlowButton1Click(Sender: TObject); 
begin 
    case cxRadioGroup1.ItemIndex of 
    0: begin 
     if MessageDlg('Are you sure ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then 
     begin 
     Data_Module.T_MAIN.First; 
     while not Data_Module.T_MAIN.Eof do begin 
      Data_Module.INS_ARCH.Close; 
      Data_Module.INS_ARCH.SQL.Clear; 
      Data_Module.INS_ARCH.SQL.Text :='INSERT INTO ARCHIVE (T_ID,FOR_DATE,DONE_WHEN)' 
      + 'SELECT :a3,:a4,:a5 FROM T_MAIN WHERE ACCOMPLISHED =True '; 
      Data_Module.INS_ARCH.Params.ParamByName('a3').AsInteger := Data_Module.T_MAIN.FieldByName('T_ID').AsInteger; 
      Data_Module.INS_ARCH.Params.ParamByName('a4').AsDate := Data_Module.T_MAIN.FieldByName('FOR_DATE').AsDateTime; 
      Data_Module.INS_ARCH.Params.ParamByName('a5').AsDate := Data_Module.T_MAIN.FieldByName('DONE_WHEN').AsDateTime; 
      Data_Module.T_MAIN.Next; 
      Data_Module.INS_ARCH.ExecSQL; 
     end; 
     end else begin 
     Exit; 
     end; //MessageDlg 
    end; //case = 0 
    end; //case 
end; //procedure 

И еще одна записка, так как они находятся внутри модуля данных, не эта процедура также может быть внутри модуля данных? Меня беспокоит, как каждый звонок ссылается на Data_Module..

+0

are you shure 'SELECT 1000,2015-08-22,2015-08-01 FROM T_MAIN' является допустимым оператором SELECT ??? –

+0

@ moskito-x Нет, это не так, но я оставляю свой ответ, поскольку он по-прежнему полезен. –