Topic: [Скрипт] Импорт CSV файла в базу

Импорт данных из CSV файла в базу данных

procedure Form1_Button2_OnClick (Sender: string; var Cancel: boolean);
var
   OpenDialog: TOpenDialog;
   sl: TStringList;
   arrStr: array of string;

   i,c: integer;
begin
     OpenDialog := TOpenDialog.Create(Form1);
     OpenDialog.InitialDir := ExtractFileDir(Application.Exename);

     if OpenDialog.Execute then
     begin
          sl := TStringList.Create;
          sl.LoadFromFile (OpenDialog.FileName);


          c := sl.Count - 1;
          for i := 0 to c do
          begin
               arrStr := SplitString(sl[i], ';');

               // LastName
               if arrStr[0] <> '' then arrStr[0] := ''''+ ReplaceStr(arrStr[0], '''', '''''') + ''''
                   else arrStr[0] := 'NULL';

               // FirstName
               if arrStr[1] <> '' then arrStr[1] := ''''+ ReplaceStr(arrStr[1], '''', '''''') + ''''
                   else arrStr[1] := 'NULL';

               SQLExecute ('INSERT INTO base (lastname, firstname) VALUES ('+ arrStr[0] +','+ arrStr[1]+');');


               Form1.Label1.Caption := IntToStr(i+1) + ' of ' + IntToStr(c+1);
               Application.ProcessMessages;
          end;



          sl.Free;
          Form1.TableGrid1.dbUpdate;
     end;
     OpenDialog.Free;
end;


begin
end.

Проект с примером:

Post's attachments

Attachment icon Import CSV simple.zip 5 kb, 640 downloads since 2015-05-01 

Dmitry.

Re: [Скрипт] Импорт CSV файла в базу

Дмитрий а в чем отличие данного примера от других?
И не могли бы Вы прокомментировать данный участок, не  совсем понимаю что к чему:

begin
               arrStr := SplitString(sl[i], ';');

               // LastName
               if arrStr[0] <> '' then arrStr[0] := ''''+ ReplaceStr(arrStr[0], '''', '''''') + ''''
                   else arrStr[0] := 'NULL';

               // FirstName
               if arrStr[1] <> '' then arrStr[1] := ''''+ ReplaceStr(arrStr[1], '''', '''''') + ''''
                   else arrStr[1] := 'NULL';

               SQLExecute ('INSERT INTO base (lastname, firstname) VALUES ('+ arrStr[0] +','+ arrStr[1]+');');


               Form1.Label1.Caption := IntToStr(i+1) + ' of ' + IntToStr(c+1);
               Application.ProcessMessages;
          end;

Спасибо.

Re: [Скрипт] Импорт CSV файла в базу

Данный пример, в отличие от других, максимально упрощен.
Если кратко, то в переменную sl загружается CSV файл.
Затем с помощью цикла проходим каждую строку из sl
где строку разбиваем на отдельные столбцы в массив arrStr

procedure Form1_Button2_OnClick (Sender: string; var Cancel: boolean);
var
   OpenDialog: TOpenDialog;
   sl: TStringList;
   arrStr: array of string;

   i,c: integer;
begin
     OpenDialog := TOpenDialog.Create(Form1);
     OpenDialog.InitialDir := ExtractFileDir(Application.Exename);

     if OpenDialog.Execute then
     begin
          sl := TStringList.Create;
          sl.LoadFromFile (OpenDialog.FileName);


          c := sl.Count - 1;
          for i := 0 to c do
          begin
               arrStr := SplitString(sl[i], ';'); // разбиваем строку (sl[i]) на массив (arrStr)

               // LastName
               // если arrStr[0] содержит текст, делаем экранирование одиночных кавычек (ReplaceStr), иначе присваиваем значение NULL
               if arrStr[0] <> '' then arrStr[0] := ''''+ ReplaceStr(arrStr[0], '''', '''''') + ''''
                   else arrStr[0] := 'NULL';

               // FirstName
               if arrStr[1] <> '' then arrStr[1] := ''''+ ReplaceStr(arrStr[1], '''', '''''') + ''''
                   else arrStr[1] := 'NULL';

               SQLExecute ('INSERT INTO base (lastname, firstname) VALUES ('+ arrStr[0] +','+ arrStr[1]+');');


               Form1.Label1.Caption := IntToStr(i+1) + ' of ' + IntToStr(c+1);
               Application.ProcessMessages;
          end;



          sl.Free;
          Form1.TableGrid1.dbUpdate;
     end;
     OpenDialog.Free;
end;


begin
end.
Dmitry.

Re: [Скрипт] Импорт CSV файла в базу

Спасибо за ответ. Так и предполагал. И если с большей частью кода мне визуально понятно, то больше интересует структура данной строки

 if arrStr[1] <> '' then arrStr[1] := ''''+ ReplaceStr(arrStr[1], '''', '''''') + ''''

слишком много для меня знаков  такого вида, ("") и просто не могу никак сообразить за что они в таком количестве отвечают.  :-(
А структура реально упростилась.

Re: [Скрипт] Импорт CSV файла в базу

например 4 апострофа
первые и последние, как обычно, используются для формирования строки
а второй и третий обозначает как бы один апостроф в данной строке, как бы экранирует его.

Dmitry.

Re: [Скрипт] Импорт CSV файла в базу

Дмитрий здравствуйте , опять я. Никак не могу понять как в данном варианте можно организовать импорт если поле имеет значение "дата" либо является словарём т.е. id_name.  Ив предыдущих вариантах у меня все работает, но там сильно усложнённый код, с кучей ненужных переменных. Буду премного благодарен за образцы строк кода.

Re: [Скрипт] Импорт CSV файла в базу

wertyby
Можете скачать данный пример:
http://myvisualdatabase.com/forum/misc. … download=1


в данном примере есть код, как импортировать дату:

               //0 sDate
               if arrStr[0]<>'' then
                  sDate := '"'+ FormatDateTime('yyyy-MM-DD 00:00:00.000', StrToDate(arrStr[0])) + '"'
                  else sDate := 'NULL';


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

               //2 id_raion
               if arrStr[2] <> '' then
               begin
                    sid_raion := SQLExecute ('SELECT id FROM raion WHERE raion LIKE "' + arrStr[2] +'"');
                    if sid_raion = '' then
                    begin
                         SQLExecute ('INSERT INTO raion (raion) VALUES ("'+ arrStr[2] +'");');
                         sid_raion := IntToStr(Last_Insert_id('raion'));
                         if sid_raion = '-1' then sid_raion := 'NULL';
                    end;
               end else sid_raion := 'NULL';
Dmitry.

Re: [Скрипт] Импорт CSV файла в базу

Ок. Спасибо. Как всегда выручаете. Пойду разбираться.

9 (edited by 2025565 2016-09-05 14:48:41)

Re: [Скрипт] Импорт CSV файла в базу

Приветствую Вас .
Подскажи пожалуйста Дмитрий а как реализовать Импорт из CSV файла в таблицу без ( дубликатов строк ) по вашему примеру
Import CSV simple.zip
пересмотрел весь сайт так и не нашёл ответа на свой вопрос .
Заранее благодарен Владимир

если импортирую тот же CSV файл  в таблицу  ,что бы небыло дубликатов а добавилась только новая строка если она такая появилась .
Еще раз благодарен .

Re: [Скрипт] Импорт CSV файла в базу

2025565 wrote:

Приветствую Вас .
Подскажи пожалуйста Дмитрий а как реализовать Импорт из CSV файла в таблицу без ( дубликатов строк ) по вашему примеру
Import CSV simple.zip
пересмотрел весь сайт так и не нашёл ответа на свой вопрос .
Заранее благодарен Владимир

если импортирую тот же CSV файл  в таблицу  ,что бы небыло дубликатов а добавилась только новая строка если она такая появилась .
Еще раз благодарен .

Приветствую,


чтобы добавить проверку на дубликат, замените эту строку

               SQLExecute ('INSERT INTO base (lastname, firstname) VALUES ('+ arrStr[0] +','+ arrStr[1]+');');

на

               if SQLExecute('SELECT COUNT(id) FROM base WHERE lastname = ' + arrStr[0] + ' AND firstname = ' + arrStr[1]) = 0 then
                   SQLExecute ('INSERT INTO base (lastname, firstname) VALUES ('+ arrStr[0] +','+ arrStr[1]+');');
Dmitry.

Re: [Скрипт] Импорт CSV файла в базу

Огромное Спасибо
будем разбираться.

12 (edited by pt.82 2016-12-09 06:57:03)

Re: [Скрипт] Импорт CSV файла в базу

Добрый день! опробывал 2 этих (с простой записью в таблицу и с заполнением справочника) импорта все ок, но если в cvs файле в записи содержится символы ; [ ] ' . , то в первом случае в базу эти сисмволы не загружаются, во втором случае импорт затыкается. Возможно ли импортировать записи с такими символы, при ручном ввводе (добавление записей через форму) сохраняютя эти сисмволы без проблем.

Re: [Скрипт] Импорт CSV файла в базу

pt.82 wrote:

Добрый день! опробывал 2 этих (с простой записью в таблицу и с заполнением справочника) импорта все ок, но если в cvs файле в записи содержится символы ; [ ] ' . , то в первом случае в базу эти сисмволы не загружаются, во втором случае импорт затыкается. Возможно ли импортировать записи с такими символы, при ручном ввводе (добавление записей через форму) сохраняютя эти сисмволы без проблем.

Скорей всего вы забыли выполнить экранизацию текста, пример

if arrStr[1] <> '' then arrStr[1] := ''''+ ReplaceStr(arrStr[1], '''', '''''') + '''';
Dmitry.

14 (edited by pt.82 2016-12-13 07:55:50)

Re: [Скрипт] Импорт CSV файла в базу

хм вот скрипт вро де все экранировано, этим скриптом загружаю запись где нет никах символов одни лат буквы поле lat все ок, но если встречается символ ";" то запись получается вида например должно получится fdr;tdy, а импортируется fdr т.е. только до символа ";" дальше обрыв, затем начинается обработка следующей записи вот скрипт 1-го импорта

procedure Form1_Button4_OnClick (Sender: string; var Cancel: boolean);

var
   OpenDialog: TOpenDialog;
   sl: TStringList;
   arrStr: array of string;

   i,c: integer;
begin
     SQLExecute('delete from db_main') ;
     OpenDialog := TOpenDialog.Create(Form1);
     OpenDialog.InitialDir := ExtractFileDir(Application.Exename);

     if OpenDialog.Execute then
     begin
          sl := TStringList.Create;
          sl.LoadFromFile (OpenDialog.FileName);


          c := sl.Count - 1;
          for i := 0 to c do
          begin
               arrStr := SplitString(sl[i], ';');

               if arrStr[0] <> '' then arrStr[0] := ''''+ ReplaceStr(arrStr[0], '''', '''''') + ''''
                   else arrStr[0] := 'NULL';

               if arrStr[1] <> '' then arrStr[1] := ''''+ ReplaceStr(arrStr[1], '''', '''''') + ''''
                   else arrStr[1] := 'NULL';
               if arrStr[2] <> '' then arrStr[2] := ''''+ ReplaceStr(arrStr[2], '''', '''''') + ''''
                   else arrStr[1] := 'NULL';
               if arrStr[3] <> '' then arrStr[3] := ''''+ ReplaceStr(arrStr[3], '''', '''''') + ''''
                   else arrStr[1] := 'NULL';
               if arrStr[4] <> '' then arrStr[4] := ''''+ ReplaceStr(arrStr[4], '''', '''''') + ''''
                   else arrStr[1] := 'NULL';


               SQLExecute ('INSERT INTO db_MAIN (Nkart, uch, FIO, SEX, lat) VALUES ('+ arrStr[0] +','+ arrStr[1]+','+ arrStr[2]+','+ arrStr[3]+','+ arrStr[4]+');');


               Form1.Label2.Caption := IntToStr(i+1) + ' of ' + IntToStr(c+1);
               Application.ProcessMessages;
          end;


          sl.Free;
          Form1.TableGrid1.dbUpdate;
     end;
     OpenDialog.Free;
end;

попробывал из первого поста в cvs файл в имена и фамилии вставить символы ";" "[", при импорте также обрезалось т.е в базу загрузилось только до символов ; или [, не могу разобраться

Re: [Скрипт] Импорт CSV файла в базу

pt.82
Проверил на SQLite и на MySQL, импортирует.
Приложите пожалуйста ваш проект, CSV файл для импорта и сообщите какую версию программы вы используете?

Dmitry.

16 (edited by pt.82 2016-12-15 05:46:34)

Re: [Скрипт] Импорт CSV файла в базу

Версия 2,8. Если не трудно как будет время посмотрите импорт2 (где загружается справочник) выскакивает ошибка.  в импорте1 не выдает ошибку, но и сисмволы не загружает на людей у кого встречаются в именах буквы "ж", "э", "х", "ю", "б". обьясню для чего: в поле LAT импортируются значения полей NKART+FIO, только все буквы русской раскладки клавиатуры заменены на соответсвующие латинские, т.е. й=q ц=w... х=[... ж=;. для чего - для того чтобы можно было сформировать qr код, сканер не читает латиницу, в qr код да все засовывается и кирилица читается телефоном-приложением, но usb-сканером упорно не хочет воспримнимать кирилицу (может что то со сканером). итог я в qr код засовываю латинские символы, которые соответсвуют русской раскладке, а сканер ставлю в режим эмуляции клавиатуры, и сканер просто печатает латинские символы в русской раскладке, ух да понимаю, что это костыль с изолентой, но я не нашел др выхода. заранее спасибо!!!

Post's attachments

Attachment icon qrkod1.rar 525.79 kb, 20 downloads since 2016-12-14 

Re: [Скрипт] Импорт CSV файла в базу

По кнопке import2 у меня возникают ошибки при импорте, т.к. нет экранизации символов ' и нужно использовать символ ' вместо ", должно быть так

                 //3 sFIO
               if arrStr[2]<>'' then sFIO := ''''+ReplaceStr(arrStr[2], '''', '''''')+'''' else sFIO := 'NULL';

               //4 sSEX
               if arrStr[3]<>'' then sSEX := ''''+ReplaceStr(arrStr[3], '''', '''''')+'''' else sSEX := 'NULL';

               //5 sLat
               if arrStr[4]<>'' then sLat := ''''+ReplaceStr(arrStr[4], '''', '''''')+'''' else sLat := 'NULL';


скрипт импорта от кнопки "import" у меня работает, в присланной вами БД также присутствуют записи, в которых содержится например буква ж

Dmitry.

18 (edited by pt.82 2016-12-16 03:16:32)

Re: [Скрипт] Импорт CSV файла в базу

я извиняюсь за назойливость, например в cvs файле есть записи в поле Lat начинается с символа ";"  этот символ соответсвует кkавиша ж=;
так вот при импорте где присутствует ; запись в поле лат обрывается не импортируется до конца.
например записи в cvs
Nkart                 FIO                                                      SEX    Lat
Ж760001    76    Жукова Пелагея Васильевна            Ж      ;760001  ;erjdf Gtkfutz Dfcbkmtdyf
Ж760002    76    Жиманова Надежда Александровна    Ж    ;760002  ;bvfyjdf Yflt;lf Fktrcfylhjdyf
Ж760003    76    Жиров Никита Андреевич                    М    ;760003  ;bhjd Ybrbnf Fylhttdbx

что получается при импорте
Nkart                 FIO                                                      SEX    Lat
Ж760001    76    Жукова Пелагея Васильевна            Ж      "
Ж760002    76    Жиманова Надежда Александровна    Ж    "
Ж760003    76    Жиров Никита Андреевич                    М    "

также если символ ; стоит в середине слова получается так
cvs
Д780069    78    Долженко Екатерина Андреевна    Ж    L780069  Ljk;tyrj Trfnthbyf Fylhttdyf
при импорте
Д780069    78    Долженко Екатерина Андреевна    Ж    L780069  "Ljk
т.е. доходит до символа ; и обрыв

и при импорт1 тоже самое.
Итого: импорты работают русские символы все без проблем импортируются, но в часности символ ; не импортирует

ну и попутный вопрос как можно прервать импорт какой скрипт нужен

Re: [Скрипт] Импорт CSV файла в базу

pt.82
Это происходит потому что у вас символ ; уже используйте как служебный в качестве разделителя полей.
Вам необходимо в чтобы в CSV файле был такой символ-разделитель, который не присутсововал бы в данных, а лучше сделать комбинацию символов в качестве разделителя.

Dmitry.

20 (edited by pt.82 2016-12-18 08:37:09)

Re: [Скрипт] Импорт CSV файла в базу

да все теперь понятно! работает ок! СПАСИБО!!!!!! а можно при импорте или после импорта по нажатию на кнопку,  чтобы значения 2 полей сливались в 3-е поле и затем символы этого  3- поля заменялись в определенном порядке напрмер а:=j или й:=v например 1поле = а, 2поле =й должно при импорте получиться 3поле=jv. Если не сложно натолкните на мысль, ну если нет то и так пойдет импорт в принципе устраивает

Re: [Скрипт] Импорт CSV файла в базу

pt.82
Обычно в базе данных не принято хранить информацию, если ее можно получить из других полей. Иначе можно получить рассогласование данных, т.е. измените одно поле, а второе уже будет не соотвествовать первому.


При необходимости можете вычисляемым полем склеить два поля, затем скриптом сделать преобразование данных.

Dmitry.

22 (edited by FROST Yesterday 09:02:37)

Re: [Скрипт] Импорт CSV файла в базу

Приветствую уважаемые знатоки. Частный случай импорта данных из csv файла в базу.

Задача состоит в том чтобы данные вида DD.MM.YYYY (в csv таким образом представлена дата) перенести в базу, где дата представлена тремя столбцами:
1столбец: CJD ( хронологический юлианский день тип поля INTGER);
2столбец: день месяца INTEGER;
3столбец: номер месяца INTEGER.

Пожалуйста укажите на функции, которыми нужно пользоваться при решении данной задачи. Если можно приведите фрагмент кода с последовательными преобразованиями типов данных.

Предвидя возможные ответы, хочу обратить внимание на то обстоятельство, что все функции оперируют с типом данных TDateTime, в котором дата сохраняется как число дней с 30 декабря 1899 (источник информации), а юлианское представление считает число дней, прошедших начиная с полудня 1 января 4713 до н. э. юлианского календаря или, что то же самое, 24 ноября 4714 г. до н. э. григорианского календаря. Прошу помощи тех, кто разобрался с этим, у кого эта чехорда чисел не вызывает смятение как у меня.

Re: [Скрипт] Импорт CSV файла в базу

Приветствую.


Попробуйте так

procedure Form1_Button1_OnClick (Sender: string; var Cancel: boolean);
var
    s: string;
    d, m, y: integer;
begin
    s := '26.12.2016'; // ваша дата из CSV файла

    if ValidInt(s[1]+s[2]) then d := StrToInt(s[1]+s[2]);
    if ValidInt(s[4]+s[5]) then m := StrToInt(s[4]+s[5]);
    if ValidInt(s[7]+s[8]+s[9]+s[10]) then y := StrToInt(s[7]+s[8]+s[9]+s[10]);

    ShowMessage(d);
    ShowMessage(m);
    ShowMessage(y);
end;
Dmitry.

24

Re: [Скрипт] Импорт CSV файла в базу

Дмитрий, благодарю за ответ.
Благодаря предложенному коду мы сможем строку вида DD.MM.YYYY разбить на составляющие DD и MM и YYYY. Правда возникнет проблема если входные данные будут иметь вид D.MM.YYYY (для дат до 10го числа месяца). Поэтому хотелось бы работать с типом [array of string] как в примере из начала ветки обсуждения, использовав функцию SplitString([String], '.') (контекстный вопрос - с точкой сработает?). После получения трех элементов в [array of string] можно обрабатывать (спасибо за обозначенную возможность проверки типа данных)

if ValidInt(array of string [n]) then ...

Кроме этого нам потребуется применить формулу расчета CJD (хронологический юлианский день).
И уже последним шагом выполнять загрузку в базу. Конечно нужно еще правильно составить циклы и подциклы (в случае даты одному полю из csv будет соответствовать три поля в базе). Буду "кумекать". Если кто желает - присоединяйтесь. А может у кого уже есть и готовое решение.