Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Создание уникального поля 2

Delphi , Базы данных , Поля

Создание уникального поля 2

Автор: Serg

Вот мой вариант получения очередного уникального (возрастающего) ID

По полю FieldName строится уникальный индекс

Заодно скажу, что использование AutoInc не есть мудрое решение. А если надо пересобрать таблицы ?


{ Get max key value}
function quGetMaxID_(tbName,FieldName: String): LongInt;
begin
  with TQuery.Create(nil) do
    try
      DatabaseName := DBname;
      SQL.Add('SELECT MAX('+FieldName+') FROM ' + QuotedStr(tbName));
      Open;
      result := Fields[0].AsInteger + 1;
    finally
      Close;
      Free;
    end;
end;

{ insert new record and return new ID value}
function quInsertBlankSQL_(tbName,fName: string; var id: Longint): boolean;
var
  i: integer;
begin
  Result := False;
  for i:=1 to RepeateAccess do
  begin
    id := quGetMaxID_(tbName,fName);
    Result := quInsertKeySQL_(tbName,fName,id);
    if Result then
      Break;
  end;
end;

{ Insert record for  ID}
function quInsertKeySQL_(tbName, KeyField: string;
 KeyValue: Longint): boolean;
var
  i: integer;
  str: string;
begin
  Result := False;
  str := 'INSERT INTO '+tbName+' ('+ KeyField + ')'+
   ' VALUES ('+IntToStr(KeyValue)+')';
  for i:=1 to gRptAccess do
  begin
    Result := quExecuteSQL_(str);
    if Result then
      Break;
  end;
end;

function quExecuteSQL_(SQLstring: string): boolean;
begin
  with quCreateTmp_(SQLstring) do
  begin
    try
      ExecSQL;
      Result := True;
    except
      on E: Exception do
      begin
        Result := False;
      end;
    end;
    Free;
  end;
end;

function quCreateTmp_(SQLstring: string): TQuery;
begin
  Result:= TQuery.Create(nil);
  with Result do
  begin
    DatabaseName := DBname;
    SQL.Text := SQLString;
  end;
end;

Перевод контента на русский язык:

Код, который вы предоставили, - это набор функций Delphi, которые предназначены для создания уникального, инкрементирующегося ID для таблицы. Подход использует комбинацию запросов к максимальному значению в указанном поле и вставки нового записи с инкрементированным ID.

Вот некоторые наблюдения и предложения:

  1. Функция quGetMaxID_ ответственна за получение максимального значения из указанного поля. Хорошая практика - проверять, есть ли записи в таблице перед попыткой получить максимальное значение.
  2. В функции quInsertBlankSQL_ вы используете цикл для повторения процесса вставки до тех пор, пока операция не будет успешной. Это может потенциально привести к проблемам с производительностью и ошибкам, если операция вставки fails по какой-то причине. Лучше было бы обрабатывать исключения и повторы в более контролируемом порядке.
  3. Функция quInsertKeySQL_ вставляет новую запись в указанную таблицу с предоставленным значением ID. Однако, не ясно, должна ли эта функция также обновлять любые автоматически инкрементирующиеся поля или первичные ключи.
  4. Функция quExecuteSQL_ используется для выполнения SQL-запросов. Она создает временный объект запроса и пытается выполнить строку SQL. Если возникает исключение при выполнении, она возвращает False. Это можно улучшить, предоставляя более детальные сообщения об ошибках или обрабатывая конкретные исключения differently.
  5. Функция quCreateTmp_ создает новый объект запроса TQuery с предоставленной строкой SQL. Однако, она не настраивает другие свойства объекта запроса, такие как имя базы данных, соединение или тип курсора.

Альтернативный подход к созданию уникальных ID:

Вместо использования комбинации запросов и циклов можно создать одиночную хранимую процедуру, которая обрабатывает процесс генерации и вставки ID. Это позволит более эффективно и надежно управлять ID.

Например, вы можете создать хранимую процедуру usp_GetNextID, которая принимает имя таблицы и имя поля как параметры, получает максимальное значение из указанного поля, инкрементирует его на 1 и возвращает новое значение ID. Затем можно использовать эту хранимую процедуру в вашем коде Delphi для получения следующего доступного ID.

Вот пример реализации хранимой процедуры usp_GetNextID:

CREATE PROCEDURE usp_GetNextID  (@tableName NVARCHAR(50),  @fieldName NVARCHAR(50))
AS
BEGIN
    DECLARE  @maxValue INT,  @nextID INT

    SELECT  @maxValue  = MAX(@fieldName) FROM  @tableName

    SET  @nextID  =  @maxValue  + 1

    RETURN  @nextID
END

Вы можете вызвать эту хранимую процедуру из вашего кода Delphi с помощью объекта TADOQuery или TSQLQuery:

procedure TForm1.GetNextId;
var
  q: TADOQuery;
begin
  q := TADOQuery.Create(nil);
  try
    q.Connection := dbConnection;
    q.SQL := 'usp_GetNextID ''myTable'', ''myField''';
    q.Open;
    if q.Record then
      MyIdValue := q.FieldByName('myField').AsInteger + 1
    else
      MyIdValue := 1;
  finally
    q.Free;
  end;
end;

Этот подход более эффективен и надежен, чем оригинальный implementation, поскольку он использует одиночную хранимую процедуру для обработки генерации и вставки ID. Он также обеспечивает лучшее обрабатывание ошибок и позволяет более гибко управлять ID.

В статье рассматриваются способы создания уникального поля в базе данных, включая использование индекса по полю FieldName и алгоритм для получения очередного уникального ID.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Поля ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-04-01 09:44:39/0.0039849281311035/0