Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.003 c
1-90612
Dinara
2002-02-12 23:02
2002.02.28
ListView


3-90490
YurikKuk
2002-02-04 03:56
2002.02.28
Настройка BDE


1-90560
Andreika
2002-02-11 21:55
2002.02.28
Проблема с MDI-фрмой


1-90573
chelobaka
2002-02-11 17:04
2002.02.28
Делал проект под win2000, перенес на 98 - не работает. Помогите советом, плс.


3-90510
HDD
2002-02-04 05:35
2002.02.28
Допоможите гарны хлопчики и дивченки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский