Приветствую Вас Гость | RSS

Меню сайта

Реклама

Категории раздела
ADO [17]
ASCII и CSV [12]
Access [20]
Alias [24]
BDE [37]
BLOB поля [19]
Clipper [2]
DB2 [2]
DBASE и DBF [26]
Fox Pro [1]
Interbase [21]
MSSQL [0]
ODBC [10]
Oracle [0]
Paradox [0]
SQL [29]
Sybase [1]
База данных [0]
Закладки [2]
Записи [0]
Индексы [10]
Компоненты и Базы данных [0]
Модуль данных [3]
Отчеты [2]
Ошибки БД [17]
Поиск [16]
Поля [0]
Сортировка и Фильтр [6]
Таблицы [0]

Наш опрос
Оцените мой сайт
Всего ответов: 30

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Форма входа

Главная » Статьи » Базы данных » SQL

Библиотека для создания динамических SQL скриптов

Библиотека для организации поисковой системы в произвольной БД с помощью динамических SQL запросов.

Описание:

Результатом работы функции:


Search_out(_путь : string): TConrolSearch;

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

Функция возвращает значение - код ошибки при формировании запроса. Если 0, то запрос сформирован удачно, в противном случае формируется код ошибки (например 1, если послан нулевой запрос). Ошибки младших байтов от 0..4 не являются критическими в плане неправильного формирования запроса. Старшие байты от 5..8 вызывают критические ошибки (TSQL не может выполнить запрос).

Перед вызовом функции, необходимо задать параметры объекта для формирования файла sql запроса.

Описание переменыых объекта Param_:

table_count
кол-во используемых таблиц
tables[1]...tables[table_count]
список используемых таблиц

Например:


tables_count := 2;
tables[1] := 'uchet';
tables[2] := 'ispol';

Param_.Count
количество параметров поиска
.Refernce[i], где 0<i<=Param_.Count
определяет к какой таблице ссылается параметр.

Например (2 таблицы, 9 параметров):


Param_.Count := 9;
if (UchetCheck.Checked = true) and (IspolCheck.Checked = true) then
begin
tables_count := 2;
tables[1] := 'uchet';
tables[2] := 'ispol';
Param_.Reference[1] := 1;
Param_.Reference[2] := 1;
Param_.Reference[3] := 1;
Param_.Reference[4] := 2;
Param_.Reference[5] := 1;
Param_.Reference[6] := 1;
Param_.Reference[8] := 2;
Param_.Reference[9] := 2;
end;

.Field_Name[i] : String, 0<i<=Param_.Count
список полей таблиц, связанных с параметрами поиска
.param_type[i] : PType, 0<i<=Param_.Count
тип параметра ('S' - строка, 'D' -дата, 'C' - словарь, 'N' - числовой)
.Inverse[i] : EqType : boolean
определяет использование '=' или '!=' с данным параметром (кроме типов 'C' и 'N')
.Equality[i] : EqType : boolean
определяет полное или частичное совпадение параметра поиска (только для типа 'S')
.param_value[i] : StrArr
определяет значения параметров
.param_name : string
текущее значение параметра
.NumEq : ETL (:EqTypeList)
определяет использование знака '=', '>', '<' вместе с типом 'N'
Процедура Clear_Search
очищает значения param_value в диапазоне от 1..50, рекомендуется использовать для очистки старых параметров поиска перед заданием новых параметров. По умолчанию процедура включена в основную функцию search_out.
Функция Param_Set
используется для установки параметров кретерия поиска.
c_d = 'C'
создать таблицу, 'D', удалить таблицу, 'N' - не создавать таблицу

unit Search_engine;

interface

const
err0 = 'Search_out';
eq = '=';
min = '<';
max = '>';
eq_min = '=<';
eq_max = '>=';
min_max = '!=';


SEL = 'SELECT';
FROM = 'FROM ';
U = '''';
C = ',';
C_ = '.';
P = ' :PARAM_';
L = ' LIKE ';
A = ' AND ';
PP = '+';
PR = '%';
BTW = ' BETWEEN ';
N = ' !';
UP = 'upper';
ORD_ = 'ORDER BY ';

type PTypeList = 'A'..'Z';
type TFieldList = array [1..50] of string;
type EqTypeList = string[2];
type TControlSearch = record
SetByte: byte;
GetByteString: array [0..7] of string;
end;

type StrArr = array [1..50] of string[30];
RefArr = array [1..50] of integer;
PType = array [1..50] of PTypeList; // 'S' - string, 'D' - dateTime, 'N' - numeric, 'C' - vocabulary
EqType = array [1..50] of boolean;
TOrder = array [1..50] of integer;
ETL = array [1..50] of string[2];
Param = object
param_value : StrArr;
Field_Name : StrArr;
Reference : RefArr;
Count : integer;
param_name : string;
param_type : PType;
Equality : EqType;
Inverse : EqType; //Working only if Equality[i] = true
NumEq : ETL;
Order : TOrder;
end;

type Param_Result_ = object
param_value : StrArr;
Field_Name : StrArr;
Reference : RefArr;
Count : integer;
param_name : string;
param_type : PType;
Equality : EqType;
Inverse : EqType;
NumEq : ETL;
Order : TOrder;
end;


var
search_param_count, tables_count: integer;

Sql_File : Text;
tables : StrArr;
Param_ : Param;
Param_Result : Param_Result_;
ListField : TFieldList;
ListFieldCount : integer;
path_ : string;

procedure Clear_Search;
procedure SetOrder(o : integer;str : string);
function Search_out(path : string) : TControlSearch;
function Param_Set(NumParam: integer; FieldName: string; Ref: integer;
Equal: boolean; P_Type: char; P_Value: variant): TControlSearch;

implementation

uses
SysUtils;

procedure Clear_Search;
var
k: integer;
begin
for k := 1 to 50 do
Param_.param_value[k] := '';
end;

function Search_out(path: string): TControlSearch;

//Error Section
const
err1 = 'ZeroCtrlString';

var
first_str : string;
i : integer;
table_str : string;
Result_param : StrArr;
CtrlString : string;
SELECT,
TMP_SELECT : string;
FieldCount : integer;
f_type : string;

begin

i := 0;
Param_Result.Count := 0;
if ListFieldCount = 0 then
SELECT := 'SELECT* FROM '
else
begin
SELECT := SEL;
TMP_SELECT := '';
for FieldCount := 1 to ListFieldCount do
begin
if FieldCount = ListFieldCount then
begin
TMP_SELECT := TMP_SELECT + ' ' + ListField[FieldCount];
break;
end;
TMP_SELECT := TMP_SELECT + ' ' + ListField[FieldCount] + C;
end;
SELECT := SELECT + ' ' + TMP_SELECT + ' ' + FROM;
end;
repeat
inc(i);
if Param_.param_value[i] <> '' then
begin
inc(Param_Result.Count);
Param_Result.param_value[Param_Result.Count] := Param_.param_value[i];
CtrlString := CtrlString + Param_.param_value[i];
Param_Result.Field_Name[Param_Result.Count] := Param_.Field_Name[i];
Param_Result.Reference[Param_Result.Count] := Param_.Reference[i];
Param_Result.Param_type[Param_Result.Count] := Param_.Param_type[i];
Param_Result.Equality[Param_Result.Count] := Param_.Equality[i];
Param_Result.Inverse[Param_Result.Count] := Param_.Inverse[i];
Param_Result.NumEq[Param_Result.Count] := Param_.NumEq[i];
end;
until
i = Param_.Count;

// 1 BIT ERROR CHECK

if CtrlString = '' then
begin
Search_out.SetByte := 1;
Search_out.GetByteString[1] := Err0 + C_ + Err1;
AssignFile(Sql_File,path);
Rewrite(Sql_File);
writeln(Sql_File,SELECT+tables[1]);
CloseFile(Sql_file);
exit;
end
else
begin
Search_out.SetByte := 0;
Search_out.GetByteString[0] := '';
end;

i := 0;
AssignFile(Sql_File,path);
path_ := path;
Rewrite(Sql_File);

if tables_count > 1 then
begin
while i <> tables_count do
begin
inc(i);
if i = tables_count then
first_str := first_str + tables[i]
else
first_str := first_str + tables[i] + C;
end; //WHILE
end
else
first_str := tables[1];


first_str := SELECT + first_str;
writeln(Sql_File,first_str);
writeln(Sql_File,'WHERE');
i := 0;
{!MAIN REPEAT!}
repeat
inc(i);
table_str := tables[param_Result.Reference[i]];
Param_Result.param_name := Param_Result.param_value[i];

//СТРОКОВЫЙ ТИП

if (Param_Result.param_type[i] = 'S') then
if i < Param_Result.Count then
begin
if Param_Result.Equality[i] = false then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
L + UP +'(' + U + Param_Result.param_name + PR + U +')' + A)
else
if Param_Result.Inverse[i] = false then
writeln(Sql_file,table_str + C_ + Param_Result.Field_Name[i] +
'='+U+ Param_Result.param_name+U+A)
else
writeln(Sql_file,table_str + C_ + Param_Result.Field_Name[i] +
N+'='+U+ Param_Result.param_name+U+A);
end
else
begin
if Param_Result.Equality[i] = false then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
L + UP + '(' + U + Param_Result.param_name + PR + U + ')')
else
if Param_Result.Inverse[i] = false then
writeln(Sql_file,table_str + C_ + Param_Result.Field_Name[i] +
'='+U+ Param_Result.param_name+U)
else
writeln(Sql_file,table_str + C_ + Param_Result.Field_Name[i] +
N+'='+U+ Param_Result.param_name+U);
end;

// ТИП ДАТА

if (Param_Result.param_type[i] = 'D') then
begin
if i + 1 < Param_Result.Count then
begin
if (Param_Result.param_type[i+1] = 'D') and
(Param_Result.Reference[i] = Param_Result.Reference[i + 1]) then
begin
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i]
+ BTW + U+Param_Result.param_name +U+ ' ' + A +U +
Param_Result.param_value[i+1]+ U + ' '+ A);i := i + 1
end
else
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i]
+'='+U+Param_Result.param_name +U+A);
end;

if (i + 1 = Param_Result.Count) and (Param_Result.param_type[i+1] <> 'D') then
begin
if (Param_Result.param_type[i+1] = 'D')
and (Param_Result.Reference[i] = Param_Result.Reference[i + 1]) then
begin
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i]
+ BTW + U+Param_Result.param_name +U+ ' ' + A +U +
Param_Result.param_value[i+1]+ U + ' '+ A);i := i + 1
end
else
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i]
+'='+U+Param_Result.param_name +U+A);
end;


if (i + 1 = Param_Result.Count) and (Param_Result.param_type[i+1] = 'D') then
begin
if (Param_Result.param_type[i+1] = 'D') and
(Param_Result.Reference[i] = Param_Result.Reference[i + 1]) then
begin
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i]
+ BTW + U+Param_Result.param_name +U+ ' ' + A +U +
Param_Result.param_value[i+1]+ U + ' ');i := i + 1
end
else
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i]
+'='+U+Param_Result.param_name +U);
end;
end;

// ТИП СЛОВАРЬ

if (Param_Result.param_type[i] = 'C') then
if i < Param_Result.Count then
begin
if Param_Result.Equality[i] = false then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
L + Param_Result.param_name + PR + A)
else
if Param_Result.Inverse[i] = false then
writeln(Sql_file,table_str + C_ + Param_Result.Field_Name[i] +
'='+ Param_Result.param_name+A)
else
writeln(Sql_file,table_str + C_ + Param_Result.Field_Name[i] +
N+'='+ Param_Result.param_name+A);
end
else
begin
if Param_Result.Equality[i] = false then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
L + Param_Result.param_name + PR )
else
if Param_Result.Inverse[i] = false then
writeln(Sql_file,table_str + C_ + Param_Result.Field_Name[i] +
'='+ Param_Result.param_name)
else
writeln(Sql_file,table_str + C_ + Param_Result.Field_Name[i] +
N+'='+ Param_Result.param_name);
end;

// ТИП ЧИСЛОВОЕ ЗНАЧЕНИЕ

if (Param_Result.param_type[i] = 'N') then
if i < Param_Result.Count then
begin
if Param_Result.NumEq[i] = eq then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
eq + Param_Result.param_name + A);
if Param_Result.NumEq[i] = min then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
min + Param_Result.param_name + A);
if Param_Result.NumEq[i] = max then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
max + Param_Result.param_name + A);
if Param_Result.NumEq[i] = eq_max then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
eq_max + Param_Result.param_name + A);
if Param_Result.NumEq[i] = eq_min then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
eq_min + Param_Result.param_name + A);
if Param_Result.NumEq[i] = min_max then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
min_max + Param_Result.param_name + A);
end
else
begin
if Param_Result.NumEq[i] = eq then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
eq + Param_Result.param_name);
if Param_Result.NumEq[i] = min then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
min + Param_Result.param_name);
if Param_Result.NumEq[i] = max then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
max + Param_Result.param_name);
if Param_Result.NumEq[i] = eq_max then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
eq_max + Param_Result.param_name);
if Param_Result.NumEq[i] = eq_min then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
eq_min + Param_Result.param_name);
if Param_Result.NumEq[i] = min_max then
writeln(Sql_File,table_str + C_ + Param_Result.Field_Name[i] +
min_max + Param_Result.param_name);
end;

{!MAIN REPEAT!}
until
i = Param_Result.Count;

CloseFile(Sql_File);
Clear_Search;
end; // END FUNCTION


function Param_Set(NumParam: integer; FieldName: string; Ref: integer;
Equal: boolean; P_Type: char; P_Value: variant): TControlSearch;
begin
Param_.Field_Name[NumParam] := FieldName;
Param_.Reference[NumParam] := Ref;
Param_.Equality[NumParam] := Equal;
Param_.param_type[NumParam] := P_Type;
Param_.param_value[NumParam] := P_value;
end; //END FUNCTION

procedure SetOrder(o: integer; str: string);
var
t_str: string;
begin
AssignFile(Sql_File,path_);
Append(Sql_File);

if str = 'N' then
begin
t_str := tables[param_.Reference[o]];
writeln(Sql_file,ORD_+t_str+'.'+Param_.Field_Name[o]);
Close(Sql_File);
end
else
begin
writeln(Sql_file,ORD_+' '+str);
Close(Sql_File);
end;
end; // END PROCEDURE

end.
Категория: SQL | Добавил: Skinner (29.07.2008)
Просмотров: 377 | Рейтинг: 0.0/0
  Delphi Lab   Главная   Регистрация   Вход  
Интересная Цитата

Поиск

Магазин


Copyright MyCorp © 2025 Хостинг от uCoz