Форум: "Базы";
Текущий архив: 2002.02.28;
Скачать: [xml.tar.bz2];
ВнизПодскажите плиз, как мне добавлять записи, в базу проверяя при этом, если она уже или нет? Найти похожие ветки
← →
dimonf (2002-02-04 19:58) [0]У меня задача добавлять из массива MyData.StringList; данные в базу.
Массив типа: 10.10.2001 0909 0234 0565 ….
10.10.2001 0234 6556 3433 ….
10.10.2001 0565 3432 3454 …. и.т.д
Предполагается что каждая следующая запись это следующий час данной даты:
10.10.10 01:00 0909 0234 0565 ….
10.10.10 02:00 0234 6556 3433 ….
10.10.10 03:00 0565 3432 3454 …. и.т.д
Как мне при добавлении записей в базу из массива не повторяться.
Вот что у меня получилось, но как хочется, не работает L
…
var Count : Integer;
ADate: TDate;
ATimes: Integer;
…
ADate:=MyStrToDate(ConvData(MyData[961],1));
For Count:=1 to MyData.Count-3 do
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add("Select * From ""+Dir+"\Base\"+NTeplo+"c.db" Where Dates=""+DateToStr(MyStrToDate(ConvData(MyData[962-Count],1)))+"" and Times=""+TimeToStr(StrToTime(IntToStr(ATimes)+":00"))+""");
Query1.Open;
Inc(ProgressCount);
Form4.Gauge1.Progress:=ProgressCount;
IF (Query1.FieldByName("Dates").Value<>MyStrToDate(ConvData(MyData[962-Count],1))) and (Query1.FieldByName("Times").Value<>StrToTime(IntToStr(ATimes)+":00")) then
begin
IF ADate=MyStrToDate(ConvData(MyData[962-Count],1)) then
begin
ATimes:=ATimes+1;
end
else ATimes:=0;
ADate:=MyStrToDate(ConvData(MyData[962-Count],1));
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add("Insert Into ""+Dir+"\Base\"+NTeplo+"c.db" Values (""+DateToStr(ADate)+"",""+IntToStr(ATimes)+":00",""+FloatTostr(StrToFloat(ConvData(MyData[962-Count],2))*0.01)+"",""+FloatToStr(StrToFloat(ConvData(MyData[962-Count],9))*0.01)+"",""+FloatToStr(StrToFloat(ConvData(MyData[962-Count],11))*0.01)+"",""+FloatToStr(StrToFloat(ConvData(MyData[962-Count],9))*0.01-StrToFloat(ConvData(MyData[962-Count],11))*0.01)+"",""+FloatToStr(StrToFloat(ConvData(MainForm.MyData[962-Count],3))*0.01)+"",""+FloatToStr(StrToFloat(ConvData(MainForm.MyData[962-Count],4))*0.01)+"",""+FloatToStr(StrToFloat(ConvData(MainForm.MyData[962-Count],3))*0.01-StrToFloat(ConvData(MainForm.MyData[962-Count],4))*0.01)+"")");
Query1.ExecSQL;
end;
end;
Как быть?
← →
Фэ (2002-02-04 20:47) [1]Есть один хороший принцип - "Позволь яблоку катиться и оно укажет тебе путь вниз..".
..
Столь "сложный" Ваш код может даже уважение вызвать.
Напомню, однако, о следующем.
Есть первичный и вторичные индексы.
Первый определяет уникальность записи, вторые помогают СУБД в сортировке.
Выберите поля по значению которых запись должна быть уникальной и постройте по ним первичный ключ.
Или постройте его по идентификатору записи, а уникальность стройте по вторичному индексу.
В любом случае, если Вы добавите запись с существующими(не уникальными сочетаничми полей), в Вашей
СУБД, какой-бы она ни была, возникнет ошибка. Отлавливайте ее и обходите.
Нужен код ?
← →
dimonf (2002-02-04 20:56) [2]Да, хотелось бы взглянуть и поучиться у умных людей.
← →
BJValentine (2002-02-04 22:30) [3]Фэ ответил правильно. Такие вещи именно так и делаются. Создай уникальный индекс на нужное поле и при сохранении записи используй приблизительно след. код:
try
Query1.post;
except
Query1.delete;
end;
Удачи!
← →
Фэ (2002-02-04 23:39) [4]Ok (типа Paradox)
Проектируем вначале таблицу().
Поля:
ID: ftInteger или ftAutoInc (Integer: 4 байта) - первичный ключ (искусственный, позволяет ссылаться на запись из других таблиц)
DREC: ftDate (TDate: double)- дата
HRS: ftWord или ftString (Word: 2 байта или Char(1)) - номер часа 1..24
FLD1: ftString ( string[4]) - Ваши значения 0909
FLD2: ftString ( string[4]) - Ваши значения..
и т.д
Итого
CREATE TABLE "EXAMPLE.DAT"
(
"ID" INTEGER,
"DREC" DATE,
"HRS" CHARACTER(1),
"FLD1" CHARACTER(4),
"FLD2" CHARACTER(4),
"FLD3" CHARACTER(4),
PRIMARY KEY ("ID")
);
CREATE UNIQUE NOCASE INDEX "UNIQ" ON "EXAMPLE.DAT" ("DREC","HRS","FLD1","FLD2","FLD3");
Далее, предположим, что Вы как-то получили массив lst: TStringList;
Организуем цикл по добавлению записей
Но предварительно, формируем SQL текст запроса
with query.sql do begin
Clear;
Add("INSERT INTO EXAMPLE (ID , DREC , HRS , FLD1 , FLD2 , FLD3)");
Add("VALUES (:ID , :DREC , :HRS , FLD1 , FLD2 , FLD3)");
end;
// не зря пробелом разделены запятые - иногда помогает
for i:=0 to lst.Count-1 do
Парсим каждую строку на свой line: TStringList (по пробелам или как-еще Ch)
line := ParseOnCh(lst[i],Ch); // придумаешь как
Каждую строку переводим в свой тип данных
// 10.10.10 01:00:04 0909 0234 0565
dt: TDate dt := StrToDate(line[0]);
hrs: string; hrs := IntToStr(round(24*Frac(StrToDateTime(line[0]+" "+line[1]))));
fld1,fld2,fld3: string; fld1 := line[2] ...
// Не обязательно так "сложно"
with query do begin
Params[0].AsInteger := id; // либо автоинкремент
Params[1].AsDateTime := dt;
Params[2].AsString := hrs;
Params[3].AsString := fld1;
Params[4].AsString := fld2;
Params[5].AsString := fld3;
end;
// Здесь выполняем
query.Prepare;
tryExecSQL_(query);
// Если напарываемся на ошибку - делаем вид, что из-за неуникальности записи и пропускаем.
// либо можно анализировать причину ошибки и т.д.
function tryExecSQL_(qu: TQuery): boolean;
begin
Result := True;
with qu do
try
ExecSQL;
except
on E: Exception do begin
Result := False;
end;
end;
end;
Рпт до окончания цикла
← →
Joric (2002-02-05 01:20) [5]насчет
------
try
Query1.post;
except
Query1.delete;
end;
--------
не очень согласен.... по моему следует
try
Query1.post;
except
Query1.cancel;
end;
← →
Фэ (2002-02-05 10:15) [6]Верно, .delete не причем, и .post и .cancel.
Это делается на уровне TDataSet автоматом методом query.ExecSQL
на основе разбора .SQL.
Скорее, если делался анализ ошибки, обнаружен повтор записи по ключу, но неключевые могут отличаться и должны быть обновлены
то делать "UPDATE.." опять же через .ExecSQL.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.02.28;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.004 c