Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Генератор SQL-запросов Insert / Update

01.01.2007

Автор: Mike Heydon

Вам ещё не надоело динамически генерировать SQL запросы insert и update ? Давайте посмотрим, как можно раз и навсегда упростить этот процесс.

Допустим Вы создавали запрос следующим образом (типы параметров Data1:string Data2: integer Data3:TdateTime)

SqlCmd := 'insert into MyTable (Field1,Field2,Field2) values (' +   
                QuotedStr(Data1) + ',' + IntToStr(Data2) + ',' + 'to_date(' 
                + QuotedStr(FormatdateTime('dd/mm/yyyy',Data3)) + ',' 
                + QuotedStr('dd/mm/yyyy') + '))'; 

{Ужасно! ещё хуже, когда количество колонок увеличивается}

А если сделать функцию типа ..

SqlCmd := SqlInsert([Data1,Data2,Variant(Data3)], 
                   'MyTable', 
                   ['Field1','Field2','Field3']); 

она эмулирует строку запроса наподобие ..

insert into MyTable

(Fields1,Field2,Field3)

values ('Sweets',934,to_date('21/05/2001','dd/mm/yyyy'))

неправда ли она более проста в использовании ?

Здесь представлены функции SqlInsert и SqlUpdate. Вы наверное заметили, что я передаю TDateTime приведённый как Variant. Причина кроется в том, что VType в array of const не имеете TDateTime типа и даты просто представлены как vtExtended.

Функция SqlInsert имеет 2 переопределённых вызова, которые позволяют Вам включить или выполнить массив имён колонок.

Посмотрим, как выглядят эти функции:

interface 
 
const CrLf = #13#10;  // Возврат и перевод каретки 
 
// Прототипы функций 
 
function SqlInsert(Values : array of const; 
                   TableName : string; 
                   ColNames : array of string) : string; overload; 
 
function SqlInsert(Values : array of const; 
                   TableName : string) : string; overload; 
 
function SqlUpdate(Values : array of const; 
                   TableName : string; 
                   ColNames : array of string; 
                   WhereClause : string) : string; 
 
// --------------------------------------------------------------------------- 
implementation 
 
// Помещаем TDateTime в Values (array of const) 
// Представлен как Variant 
 
function SqlInsert(Values : array of const; 
                   TableName : string; 
                   ColNames : array of string) : string; 
var RetVar : string; 
    i : integer; 
begin 
  RetVar := 'insert into ' + TableName + CrLf + 
            '(' + ColNames[0]; 
  for i := 1 to High(ColNames) do 
     RetVar := RetVar + ',' + ColNames[i]; 
  RetVar := RetVar + ')' + CrLf; 
 
  RetVar := RetVar + 'values ('; 
 
  for i := 0 to High(Values) do begin 
     case Values[i].VType of 
          vtInteger, 
          vtInt64    : RetVar := RetVar + IntToStr(Values[i].VInteger); 
          vtChar     : RetVar := RetVar + QuotedStr(Values[i].VChar); 
          vtString   : RetVar := RetVar + QuotedStr(Values[i].VString^); 
          vtPChar    : RetVar := RetVar + QuotedStr(Values[i].VPChar); 
          vtExtended : RetVar := RetVar + FloatToStr(Values[i].VExtended^); 
          vtAnsiString : RetVar := RetVar + 
                         QuotedStr(string(Values[i].VAnsiString)); 
          // TDateTime - иначе получаем как vtExtended 
          vtVariant  : RetVar := RetVar + 'to_date(' + 
                       QuotedStr(FormatdateTime('dd/mm/yyyy', 
                       TDateTime(Values[i].VVariant^))) + ',' + 
                       QuotedStr('dd/mm/yyyy') + ')'; 
     else 
       RetVar := RetVar + '??????'; 
     end; 
 
     RetVar := RetVar + ','; 
  end; 
 
  Delete(RetVar,length(RetVar),1); 
  RetVar := RetVar + ')'; 
  if High(Values) < High(ColNames) then 
     ShowMessage('SQL Insert - Not enough values.'); 
  if High(Values) > High(ColNames) then 
     ShowMessage('SQL Insert - Too many values.'); 
 
  Result := RetVar; 
end; 
 
 
function SqlInsert(Values : array of const; 
                   TableName : string) : string; overload; 
var RetVar : string; 
    i : integer; 
begin 
  RetVar := 'insert into ' + TableName + CrLf; 
  RetVar := RetVar + 'values ('; 
 
  for i := 0 to High(Values) do begin 
     case Values[i].VType of 
          vtInteger, 
          vtInt64    : RetVar := RetVar + IntToStr(Values[i].VInteger); 
          vtChar     : RetVar := RetVar + QuotedStr(Values[i].VChar); 
          vtString   : RetVar := RetVar + QuotedStr(Values[i].VString^); 
          vtPChar    : RetVar := RetVar + QuotedStr(Values[i].VPChar); 
          vtExtended : RetVar := RetVar + FloatToStr(Values[i].VExtended^); 
          vtAnsiString : RetVar := RetVar + 
                         QuotedStr(string(Values[i].VAnsiString)); 
          // TDateTime - иначе получаем как vtExtended 
          vtVariant  : RetVar := RetVar + 'to_date(' + 
                       QuotedStr(FormatdateTime('dd/mm/yyyy', 
                       TDateTime(Values[i].VVariant^))) + ',' + 
                       QuotedStr('dd/mm/yyyy') + ')'; 
     else 
       RetVar := RetVar + '??????'; 
     end; 
 
     RetVar := RetVar + ','; 
  end; 
 
  Delete(RetVar,length(RetVar),1); 
  RetVar := RetVar + ')'; 
 
  Result := RetVar; 
end; 
 
 
function SqlUpdate(Values : array of const; 
                   TableName : string; 
                   ColNames : array of string; 
                   WhereClause : string) : string; 
var RetVar,Parm : string; 
    i : integer; 
begin 
  RetVar := 'update ' + TableName + ' set' + CrLf; 
 
  for i := 0 to Min(High(Values),High(ColNames)) do begin 
     case Values[i].VType of 
          vtInteger, 
          vtInt64    : Parm := IntToStr(Values[i].VInteger); 
          vtChar     : Parm := QuotedStr(Values[i].VChar); 
          vtString   : Parm := QuotedStr(Values[i].VString^); 
          vtPChar    : Parm := QuotedStr(Values[i].VPChar); 
          vtExtended : Parm := FloatToStr(Values[i].VExtended^); 
          vtAnsiString : Parm := QuotedStr(string(Values[i].VAnsiString)); 
          // TDateTime - иначе получаем как vtExtended 
          vtVariant  : Parm := 'to_date(' + 
                       QuotedStr(FormatdateTime('dd/mm/yyyy', 
                       TDateTime(Values[i].VVariant^))) + ',' + 
                       QuotedStr('dd/mm/yyyy') + ')'; 
     else 
       Parm := '??????'; 
     end; 
 
     RetVar := RetVar + ColNames[i] + '=' + Parm + ','; 
  end; 
 
  Delete(RetVar,length(RetVar),1); 
  RetVar := RetVar + CrLf + 'where ' + WhereClause; 
  if High(Values) < High(ColNames) then 
     ShowMessage('SQL Update - Not enough values.'); 
  if High(Values) > High(ColNames) then 
     ShowMessage('SQL Update - Too many values.'); 
 
  Result := RetVar; 
end; 

Взято из https://forum.sources.ru