Модераторы: Rodman

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование гетов при поиске информации, Как лучше реализовать? 
V
    Опции темы
Vas
Дата 12.12.2016, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 825
Регистрация: 29.6.2005
Где: Stavropol region

Репутация: 23
Всего: 28



Цитата(Rodeon @  11.12.2016,  10:53 Найти цитируемый пост)
Чтобы не делать функцию получения максимального значения ключа, добавляем в саму таблицу для поля/ключа ID триггер

Зачем такие сложности? Чем автоинкрементное поле не угодило в MySQL?

Это сообщение отредактировал(а) Vas - 12.12.2016, 11:38


--------------------
И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин)
PM MAIL   Вверх
Rodeon
Дата 12.12.2016, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 28.8.2008
Где: Россия, Ухта

Репутация: нет
Всего: нет



Цитата(Vas @ 12.12.2016,  11:38)
Цитата(Rodeon @  11.12.2016,  10:53 Найти цитируемый пост)
Чтобы не делать функцию получения максимального значения ключа, добавляем в саму таблицу для поля/ключа ID триггер

Зачем такие сложности? Чем автоинкрементное поле не угодило в MySQL?

Эм... smile тут такая штука. На самом деле база данных стала FireByrd, а в ней нет по умолчанию поля с автоинкрементом.
Все потому, что я новичок в базах данных и только изучаю.
Сперва была MySQL, но с момента создания темы перешел на FireByrd Embedded по ряду причин, основная это автономность.

PM MAIL   Вверх
Vas
Дата 12.12.2016, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 825
Регистрация: 29.6.2005
Где: Stavropol region

Репутация: 23
Всего: 28



В таком случает триггер отличный вариант. 

[off]
Embedded умеет и мускуль smile Но капризный слегка smile
[/off]

Это сообщение отредактировал(а) Vas - 12.12.2016, 13:05


--------------------
И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин)
PM MAIL   Вверх
Rodeon
Дата 12.12.2016, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 28.8.2008
Где: Россия, Ухта

Репутация: нет
Всего: нет



Да простят меня модераторы, буду описывать план действий дальнейшего создания приложения.

Сегодня реализуем Drag & Drop файла (-ов) приказа на форму программы, открытие окна для ввода данных по приказу и сохранения всех данных в базу.
Изначально решил, что после добавления приказа, файлы (jpg, pdf) будут копироваться в определенную папку на жестком диске, рядом с программой.
Но имя им будет присвоено на основе MD5 хеша (расширение сохраняем), тем самым убиваем сразу 3 зайцев:
1. удобно проверить если уже подобный файл добавлен (совпадут хеши).
2. более короткое имя файла становится автоматом (32 символа, вместо N-го которым у нас привыкли обзывают других отделы, от этого много косяков потом бывает).
3. При несанкционированном доступе к папке фиг найдешь что-то, так как все файлы будут иметь имя 32 символа.

Собственно, таблица для хранения файлов приказов будет такой:
Первичный ключ:
Код

ALTER TABLE FILE_PRIKAZ
ADD CONSTRAINT PK_FILE_PRIKAZ
PRIMARY KEY (ID)


Сама таблицу:
Код

CREATE TABLE FILE_PRIKAZ (
    ID INTEGER NOT NULL,
    ID_PRIKAZ INTEGER,
    SHORT_NAME CHAR(37),
    FULL_NAME CHAR(255))


Создаем генератор:
Код

CREATE SEQUENCE GEN_FILE_PRIKAZ_ID


Создаем триггер автоинкремента:
Код

CREATE OR ALTER TRIGGER FILE_PRIKAZ_BI FOR FILE_PRIKAZ
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id is null) then
    new.id = gen_id(GEN_FILE_PRIKAZ_ID,1);
end


В базе:
ID - тут будет уникальный индекс.
ID_PRIKAZ - индекс на ID приказа.
SHORT_NAME - имя файла(32) + точка(1) и расширение (4)
FULL_NAME - имя файла по факту (ограничение имени файла NTFS - 255 символов)
Т.е. визуально для пользователя будет выводится FULL_NAME, фактически везде SHORT_NAME.

PM MAIL   Вверх
Rodeon
Дата 12.12.2016, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 28.8.2008
Где: Россия, Ухта

Репутация: нет
Всего: нет



Обрабатываем взброса файлов на форму (исходники нашел на просторах интернета, самую малостью изменил под свои нужды):
Для события создания формы добавляем:
Код

procedure TMainForm.FormCreate(Sender: TObject);
begin
  DragAcceptFiles(Self.Handle, True);
end;


В Uses добавляем:
Код

ShellAPI


Добавил глобальный объект:
Код

  Catcher: TFileCatcher;


Создаем новый тип:
Код

type
  TFileCatcher = class(TObject)
  private
    fDropHandle: HDROP;
    function GetFile(Idx: Integer): string;
    function GetFileCount: Integer;
    function GetPoint: TPoint;
  public
    constructor Create(DropHandle: HDROP);
    destructor Destroy; override;
    property FileCount: Integer read GetFileCount;
    property Files[Idx: Integer]: string read GetFile;
    property DropPoint: TPoint read GetPoint;
  end;


Для формы добавляем новую процедуру:
Код

type
  TMainForm = class(TForm)
    procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;


Добавляем функции, процедуры и т.д.:
Код

implementation

{$R *.dfm}

constructor TFileCatcher.Create(DropHandle: HDROP);
begin
  inherited Create;
  fDropHandle := DropHandle;
end;

destructor TFileCatcher.Destroy;
begin
  DragFinish(fDropHandle);
  inherited;
end;

function TFileCatcher.GetFile(Idx: Integer): string;
var
  FileNameLength: Integer;
begin
  FileNameLength := DragQueryFile(fDropHandle, Idx, nil, 0);
  SetLength(Result, FileNameLength);
  DragQueryFile(fDropHandle, Idx, PChar(Result), FileNameLength + 1);
end;

function TFileCatcher.GetFileCount: Integer;
begin
  Result := DragQueryFile(fDropHandle, $FFFFFFFF, nil, 0);
end;

function TFileCatcher.GetPoint: TPoint;
begin
  DragQueryPoint(fDropHandle, Result);
end;

procedure TMainForm.WMDropFiles(var Msg: TWMDropFiles);
var
  I: Integer;
  DropPoint: TPoint;
begin
  Catcher := TFileCatcher.Create(Msg.Drop);
  try
    begin {Тут у меня добавлено вызов окна заполнения данных по приказу и вывод в Memo списка файлов, чисто для визуализации, так как фактически список хранится в Catcher}
      if Not Assigned(PrikazForm) then Application.CreateForm(TPrikazForm, PrikazForm);
      PrikazForm.Show;
      for I := 0 to Pred(Catcher.FileCount) do PrikazForm.sMemo3.Lines.Add(ExtractFileName(Catcher.Files[i]));
    end;
    DropPoint := Catcher.DropPoint;
  finally
  end;
  Msg.Result := 0;
end;


Таким образом:
Catcher.FileCount у нас хранится количество файлов.
Catcher.Files[N] - имя файла номер N.

Не забываем после окончания работ с полученным списком файлов уничтожить объект:
Код

    Catcher.Free;


Это сообщение отредактировал(а) Rodeon - 12.12.2016, 14:56
PM MAIL   Вверх
Rodeon
Дата 12.12.2016, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 28.8.2008
Где: Россия, Ухта

Репутация: нет
Всего: нет



Перепробовал несколько готовых модулей получения хеша, CRC32 короткое имя, самое то MD5, собственно сам модуль:
Добавляем в программу:
Код

Uses
  md5Module


Собственно сам модуль:
Код

unit md5Module;

interface

uses
  Windows, SysUtils;


function md5(S: String): String;

implementation

type
  TArrayOfByte = Array of Byte;
  TArrayOfDWORD = Array of DWORD;
  THash = Array[0..3] of DWORD;

const
  BlockSize = 4;
  HashSize = 16;
  BuffSize = 64;


function LRot32(A: DWORD; B: Byte): DWORD;
begin
  Result:= (A shl B) or (A shr (32-B));
end;

procedure Compressor(Hash, Buffer: Pointer; IV: LongWord = 0);
var
  A, B, C, D: DWORD;
begin
  A := TArrayOfDWORD(Hash)[0];
  B := TArrayOfDWORD(Hash)[1];
  C := TArrayOfDWORD(Hash)[2];
  D := TArrayOfDWORD(Hash)[3];
  Buffer := Pointer(DWORD(Buffer) + IV);
  //
  A := B + LRot32(A + (D xor (B and (C xor D))) + TArrayOfDWORD(Buffer)[ 0] + $D76AA478,  7);
  D := A + LRot32(D + (C xor (A and (B xor C))) + TArrayOfDWORD(Buffer)[ 1] + $E8C7B756, 12);
  C := D + LRot32(C + (B xor (D and (A xor B))) + TArrayOfDWORD(Buffer)[ 2] + $242070DB, 17);
  B := C + LRot32(B + (A xor (C and (D xor A))) + TArrayOfDWORD(Buffer)[ 3] + $C1BDCEEE, 22);
  A := B + LRot32(A + (D xor (B and (C xor D))) + TArrayOfDWORD(Buffer)[ 4] + $F57C0FAF,  7);
  D := A + LRot32(D + (C xor (A and (B xor C))) + TArrayOfDWORD(Buffer)[ 5] + $4787C62A, 12);
  C := D + LRot32(C + (B xor (D and (A xor B))) + TArrayOfDWORD(Buffer)[ 6] + $A8304613, 17);
  B := C + LRot32(B + (A xor (C and (D xor A))) + TArrayOfDWORD(Buffer)[ 7] + $FD469501, 22);
  A := B + LRot32(A + (D xor (B and (C xor D))) + TArrayOfDWORD(Buffer)[ 8] + $698098D8,  7);
  D := A + LRot32(D + (C xor (A and (B xor C))) + TArrayOfDWORD(Buffer)[ 9] + $8B44F7AF, 12);
  C := D + LRot32(C + (B xor (D and (A xor B))) + TArrayOfDWORD(Buffer)[10] + $FFFF5BB1, 17);
  B := C + LRot32(B + (A xor (C and (D xor A))) + TArrayOfDWORD(Buffer)[11] + $895CD7BE, 22);
  A := B + LRot32(A + (D xor (B and (C xor D))) + TArrayOfDWORD(Buffer)[12] + $6B901122,  7);
  D := A + LRot32(D + (C xor (A and (B xor C))) + TArrayOfDWORD(Buffer)[13] + $FD987193, 12);
  C := D + LRot32(C + (B xor (D and (A xor B))) + TArrayOfDWORD(Buffer)[14] + $A679438E, 17);
  B := C + LRot32(B + (A xor (C and (D xor A))) + TArrayOfDWORD(Buffer)[15] + $49B40821, 22);

  A := B + LRot32(A + (C xor (D and (B xor C))) + TArrayOfDWORD(Buffer)[ 1] + $F61E2562,  5);
  D := A + LRot32(D + (B xor (C and (A xor B))) + TArrayOfDWORD(Buffer)[ 6] + $C040B340,  9);
  C := D + LRot32(C + (A xor (B and (D xor A))) + TArrayOfDWORD(Buffer)[11] + $265E5A51, 14);
  B := C + LRot32(B + (D xor (A and (C xor D))) + TArrayOfDWORD(Buffer)[ 0] + $E9B6C7AA, 20);
  A := B + LRot32(A + (C xor (D and (B xor C))) + TArrayOfDWORD(Buffer)[ 5] + $D62F105D,  5);
  D := A + LRot32(D + (B xor (C and (A xor B))) + TArrayOfDWORD(Buffer)[10] + $02441453,  9);
  C := D + LRot32(C + (A xor (B and (D xor A))) + TArrayOfDWORD(Buffer)[15] + $D8A1E681, 14);
  B := C + LRot32(B + (D xor (A and (C xor D))) + TArrayOfDWORD(Buffer)[ 4] + $E7D3FBC8, 20);
  A := B + LRot32(A + (C xor (D and (B xor C))) + TArrayOfDWORD(Buffer)[ 9] + $21E1CDE6,  5);
  D := A + LRot32(D + (B xor (C and (A xor B))) + TArrayOfDWORD(Buffer)[14] + $C33707D6,  9);
  C := D + LRot32(C + (A xor (B and (D xor A))) + TArrayOfDWORD(Buffer)[ 3] + $F4D50D87, 14);
  B := C + LRot32(B + (D xor (A and (C xor D))) + TArrayOfDWORD(Buffer)[ 8] + $455A14ED, 20);
  A := B + LRot32(A + (C xor (D and (B xor C))) + TArrayOfDWORD(Buffer)[13] + $A9E3E905,  5);
  D := A + LRot32(D + (B xor (C and (A xor B))) + TArrayOfDWORD(Buffer)[ 2] + $FCEFA3F8,  9);
  C := D + LRot32(C + (A xor (B and (D xor A))) + TArrayOfDWORD(Buffer)[ 7] + $676F02D9, 14);
  B := C + LRot32(B + (D xor (A and (C xor D))) + TArrayOfDWORD(Buffer)[12] + $8D2A4C8A, 20);

  A := B + LRot32(A + (B xor C xor D) + TArrayOfDWORD(Buffer)[ 5] + $FFFA3942,  4);
  D := A + LRot32(D + (A xor B xor C) + TArrayOfDWORD(Buffer)[ 8] + $8771f681, 11);
  C := D + LRot32(C + (D xor A xor B) + TArrayOfDWORD(Buffer)[11] + $6D9D6122, 16);
  B := C + LRot32(B + (C xor D xor A) + TArrayOfDWORD(Buffer)[14] + $FDE5380C, 23);
  A := B + LRot32(A + (B xor C xor D) + TArrayOfDWORD(Buffer)[ 1] + $A4BEEA44,  4);
  D := A + LRot32(D + (A xor B xor C) + TArrayOfDWORD(Buffer)[ 4] + $4BDECFA9, 11);
  C := D + LRot32(C + (D xor A xor B) + TArrayOfDWORD(Buffer)[ 7] + $F6BB4B60, 16);
  B := C + LRot32(B + (C xor D xor A) + TArrayOfDWORD(Buffer)[10] + $BEBFBC70, 23);
  A := B + LRot32(A + (B xor C xor D) + TArrayOfDWORD(Buffer)[13] + $289B7EC6,  4);
  D := A + LRot32(D + (A xor B xor C) + TArrayOfDWORD(Buffer)[ 0] + $EAA127FA, 11);
  C := D + LRot32(C + (D xor A xor B) + TArrayOfDWORD(Buffer)[ 3] + $D4EF3085, 16);
  B := C + LRot32(B + (C xor D xor A) + TArrayOfDWORD(Buffer)[ 6] + $04881D05, 23);
  A := B + LRot32(A + (B xor C xor D) + TArrayOfDWORD(Buffer)[ 9] + $D9D4D039,  4);
  D := A + LRot32(D + (A xor B xor C) + TArrayOfDWORD(Buffer)[12] + $E6DB99E5, 11);
  C := D + LRot32(C + (D xor A xor B) + TArrayOfDWORD(Buffer)[15] + $1FA27CF8, 16);
  B := C + LRot32(B + (C xor D xor A) + TArrayOfDWORD(Buffer)[ 2] + $C4AC5665, 23);

  A := B + LRot32(A + (C xor (B or (not D))) + TArrayOfDWORD(Buffer)[ 0] + $F4292244,  6);
  D := A + LRot32(D + (B xor (A or (not C))) + TArrayOfDWORD(Buffer)[ 7] + $432AFF97, 10);
  C := D + LRot32(C + (A xor (D or (not B))) + TArrayOfDWORD(Buffer)[14] + $AB9423A7, 15);
  B := C + LRot32(B + (D xor (C or (not A))) + TArrayOfDWORD(Buffer)[ 5] + $FC93A039, 21);
  A := B + LRot32(A + (C xor (B or (not D))) + TArrayOfDWORD(Buffer)[12] + $655B59C3,  6);
  D := A + LRot32(D + (B xor (A or (not C))) + TArrayOfDWORD(Buffer)[ 3] + $8F0CCC92, 10);
  C := D + LRot32(C + (A xor (D or (not B))) + TArrayOfDWORD(Buffer)[10] + $FFEFF47D, 15);
  B := C + LRot32(B + (D xor (C or (not A))) + TArrayOfDWORD(Buffer)[ 1] + $85845DD1, 21);
  A := B + LRot32(A + (C xor (B or (not D))) + TArrayOfDWORD(Buffer)[ 8] + $6FA87E4F,  6);
  D := A + LRot32(D + (B xor (A or (not C))) + TArrayOfDWORD(Buffer)[15] + $FE2CE6E0, 10);
  C := D + LRot32(C + (A xor (D or (not B))) + TArrayOfDWORD(Buffer)[ 6] + $A3014314, 15);
  B := C + LRot32(B + (D xor (C or (not A))) + TArrayOfDWORD(Buffer)[13] + $4E0811A1, 21);
  A := B + LRot32(A + (C xor (B or (not D))) + TArrayOfDWORD(Buffer)[ 4] + $F7537E82,  6);
  D := A + LRot32(D + (B xor (A or (not C))) + TArrayOfDWORD(Buffer)[11] + $BD3AF235, 10);
  C := D + LRot32(C + (A xor (D or (not B))) + TArrayOfDWORD(Buffer)[ 2] + $2AD7D2BB, 15);
  B := C + LRot32(B + (D xor (C or (not A))) + TArrayOfDWORD(Buffer)[ 9] + $EB86D391, 21);
  //
  Inc(TArrayOfDWORD(Hash)[0], A);
  Inc(TArrayOfDWORD(Hash)[1], B);
  Inc(TArrayOfDWORD(Hash)[2], C);
  Inc(TArrayOfDWORD(Hash)[3], D);
end;

function HashToStr(Hash: Pointer): String;
var
  i: Byte;
begin
  Result := '';
  for i := 0 to HashSize - 1 do
    Result := Result + IntToHex(TArrayOfByte(Hash)[i], 2);
end;

function md5(S: String): String;
var
  CurrentHash: THash;
  Len, LenHI, LenLO: LongWord;
  i: LongWord;
begin
  Result := '';
  Len := Length(S);
  LenHI := Len shr 29;
  LenLO := Len * 8;
  S := S + #$80;
  Inc(Len);

  for i := 0 to BuffSize - (Len mod BuffSize) - 1 do S := S + #0;
  if (Len mod BuffSize > 56) then
      for i := 0 to BuffSize - 1 do S := S + #0;

  TArrayOfDWORD(S)[(Length(S) div BlockSize) - 1] := LenHI;
  TArrayOfDWORD(S)[(Length(S) div BlockSize) - 2] := LenLO;

  CurrentHash[0] := $67452301;
  CurrentHash[1] := $EFCDAB89;
  CurrentHash[2] := $98BADCFE;
  CurrentHash[3] := $10325476;

  for i := 0 to (Length(S) div BuffSize) - 1 do
      Compressor(@CurrentHash, PChar(S), i * BuffSize);

  Result := LowerCase(HashToStr(@CurrentHash));
end;
end.


Вызываем следующим образом (на выходе строка длиной 32 символа):
Код

function md5(S: String): String;


Добавлено через 7 минут и 20 секунд
Для добавления в базу потребуются преобразования имени файла:
Получить имя файла, без пути и расширения:
Код

S:=ChangeFileExt(ExtractFileName(Catcher.Files[i]),'');

Получить расширение имени файла:
Код

S:=ExtractFileExt(Catcher.Files[i]);

И все вместе, получаем имя файла преобразованное в MD5 + расширение:
Код

S:=md5(ChangeFileExt(ExtractFileName(Catcher.Files[i]),''))+ExtractFileExt(Catcher.Files[i]);

PM MAIL   Вверх
Rodeon
Дата 12.12.2016, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 28.8.2008
Где: Россия, Ухта

Репутация: нет
Всего: нет



Чтобы получить ID созданной записи в таблице PRIKAZ (для увязки файлов ID_PRIKAZ.FILE_PRIKAZ к приказу) необходимо обратится к генератору:
добавим переменную, в которую будем получать ID:
Код

Var
  ID_return: Integer;

После создания записи в таблице PRIKAZ получаем ID этой записи:
Код

  with MainForm.IBQuery1 do
  begin
    SQL.Clear;
    SQL.Add('select gen_id(gen_prikaz_id, 0) from rdb$database'); {тут указан генератор, на который накручен триггер для автоинкремента, 0 для того что не увеличиваем, а берем как раз последний}
    Open;
    ID_return:=FieldByName('GEN_ID').AsInteger; 
    Close;
  end;


Теперь у нас в переменной ID_return последний ID таблицы PRIKAZ.

P.S. как оказалось в FireByrd-е мало того, что нету поля с автоинкрементом, так еще и нет метода подобному GetInsertID.
PM MAIL   Вверх
Rodeon
Дата 12.12.2016, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 28.8.2008
Где: Россия, Ухта

Репутация: нет
Всего: нет



Заполняем таблицу FILE_PRIKAZ (помним, что для поля ID.FILE_PRIKAZ ранее создан триггер-автоинкремент, в Catcher у нас хранятся файлы дропнутые на форму, в ID_return хранится ID.PRIKAZ только что созданного приказа):

Код

  If Catcher.FileCount>0 then
  Begin
    For i:=0 to Catcher.FileCount-1 do
    Begin
      with MainForm.IBQuery1 do
      begin
        Active:=false;
        Sql.Clear;
        SQL.Add('INSERT INTO FILE_PRIKAZ (ID_PRIKAZ, SHORT_NAME, FULL_NAME) VALUES');
        SQL.Add(' (:ID_PRIKAZ, :SHORT_NAME, :FULL_NAME)');
        Params[0].AsInteger := ID_return;
        Params[1].AsString := md5(ChangeFileExt(ExtractFileName(Catcher.Files[i]),''))+ExtractFileExt(Catcher.Files[i]);
        Params[2].AsString := ExtractFileName(Catcher.Files[i]);
        try
          ExecSql;
        except
          on E: Exception do
          Begin
          {×òî-òî ïîøëî íå òàê}
          End;
        end;
        Close;
        if Transaction.InTransaction then Transaction.Commit;
        CopyFile(PChar(Catcher.Files[i]),PChar(ExtractFilePath(Application.ExeName)+'Prikaz\'+md5(ChangeFileExt(ExtractFileName(Catcher.Files[i]),''))+ExtractFileExt(Catcher.Files[i])),True);
      end;
    End;
  end;


Т.е., что мы сделали:
в ID_PRIKAZ записали ID приказа.
в SHORT_NAME записали MD5 от реального имени файла + расширение сохранили
в FULL_NAME записали реальное имя файла, которое и будет участвовать в последующем в визуализации.
Помимо этого скопировали все файлы в подпапку, где лежит сама программа с новыми именами MD5 с сохранением расширения.
PM MAIL   Вверх
Rodeon
Дата 14.12.2016, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 28.8.2008
Где: Россия, Ухта

Репутация: нет
Всего: нет



Для тегов у нас таблица:
Код

CREATE TABLE PRIKAZ_TAGS (
    ID_PRIKAZ  INTEGER NOT NULL,
    ID_TAGS    INTEGER NOT NULL
);


Добавляем тэги с базу PRIKAZ_TAGS сопоставляя с индексом последнего приказа ID_return:
Код

  With MainForm.IBQuery1 do
  begin
    Transaction.Active:= False; {Если не дизактивировать будет ошибка об открытой транзакции}
    Transaction.StartTransaction; {Начинаем локальную транзакцию, далее до Commit данные в базе не появятся, тем самым все действия в цикле выполняются "виртуально"}
    for i := 0 to sCheckListBox1.Items.Count - 1 do if sCheckListBox1.Checked[i] Then
    Begin
      SQL.Text:=('INSERT INTO PRIKAZ_TAGS (ID_PRIKAZ, ID_TAGS) VALUES (:ID_PRIKAZ, :ID_TAGS)');
      ParamByname('ID_PRIKAZ').AsInteger := ID_return;
      ParamByname('ID_TAGS').AsInteger := Integer(sCheckListBox1.Items.Objects[i]);
      try
        ExecSQL;
      except
        Transaction.Rollback; {если что-то пошло не так, делаем откат}
      End;
    End;
    Transaction.Commit; {заносим строки в базу}
  End;


P.S. Да поправят меня знатоки: размер транзакции может быть до 16 мб, Commit желательно делать каждые 1000 изменений.
PM MAIL   Вверх
Google
  Дата 25.9.2017, 21:53 (ссылка)  





  Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.1162 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.