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