امروز داشتم یه خونه تکونی روی سورس های قدیمی شرکت میدادم و تصمیم گرفتم تمام Dynamic Query ها و ... رو به Stored Procedure تبدیل کنم ، تعداد این موارد خیلی بود بنابراین نوشتن متدهای تکراری برام خسته کننده بود ، 3 تا متد در یک کلاس پایه تعریف کردم که تو کل کلاس های برنامه ازشون استفاده کنم کد مربوط به این سه تابع رو اینجا قرار میدم ، به وسیله این توابع خیلی راحت میتونید Stored Procedure ها رو بدون انجام عملیات تکراری و خسته کننده مقداردهی و اجرا کنید :
تابع اول StoredProcedureExists ، بررسی میکنه Stored Procedure ی که نامش داده شده در بانک جاری که بهش متصل شدید موجود هست یا نه :
function StoredProcedureExists(const SPName: string): Boolean;
var
SPList: TStringList;
begin
// Get list of stord procedure in current database & check given sp exists in it or not
SPList := TStringList.Create;
try
ADOConnection.GetProcedureNames(SPList);
Result := (SPList.IndexOf(SPName + ';1') > 0) or
(SPList.IndexOf(SPName + ';0') > 0);
finally
SPList.Free;
end;
end;
تابع دوم FetchStoredProcParams ، لیست پارامترهای Stored Procedure ی که نامش به عنوان پارامتر داده شده رو به صورت Comma Delimited در یک رشته برمیگردونه :
function FetchStoredProcParams(const SPName: string): string;
var
ParamCount: Integer;
StoredProcedureParams: TStringList;
begin
// Return given stored procedure parameters
if StoredProcedureExists(SPName) then
begin
StoredProcedureParams := TStringList.Create;
try
with ADOStoredProc do
begin
Close;
ProcedureName := SPName;
Parameters.Refresh;
for ParamCount := 0 to Parameters.Count - 1 do
if (Parameters[ParamCount].Direction = pdInput) then
StoredProcedureParams.Add(Parameters[ParamCount].Name);
Result := StoredProcedureParams.CommaText;
end;
finally
StoredProcedureParams.Free;
end;
end;
end;
* در ضمن در تابع بالا از پارامتری هایی که به صورت Output تعریف شدن چشم پوشی شده چون اصولا بهشون نیازی نیست ، اگر بهشون نیاز داشتید خودتون تغییرش بدید .
و تابع آخر ExecuteStoredProc ، که نام یک Stored Procedure رو به همراه نام پارامترها و مقدار اون ها میگیره و اون رو اجرا میکنه :
function ExecuteStoredProc(const SPName, ParamNames: string;
ParamValues: array of const): Byte;
var
ParamCount: Integer;
StoredProcedureParams: TStringList;
begin
// Parse given parameters name
StoredProcedureParams := TStringList.Create;
try
StoredProcedureParams.CommaText := ParamNames;
// Check given param names & given param count is equal , if yes check given procedure name exits in database or no
if (StoredProcedureParams.Count = Length(ParamValues)) and
(StoredProcedureExists(SPName)) then
begin
with ADOStoredProc do
begin
Close;
ProcedureName := SPName;
Parameters.Refresh;
for ParamCount := 0 to StoredProcedureParams.Count - 1 do
begin
case ParamValues[ParamCount].VType of
vtInteger:
Parameters.ParamByName(StoredProcedureParams[ParamCount]).Value :=
ParamValues[ParamCount].VInteger;
vtBoolean:
Parameters.ParamByName(StoredProcedureParams[ParamCount]).Value :=
ParamValues[ParamCount].VBoolean;
vtExtended:
Parameters.ParamByName(StoredProcedureParams[ParamCount]).Value :=
Single(ParamValues[ParamCount].VExtended);
vtUnicodeString:
Parameters.ParamByName(StoredProcedureParams[ParamCount]).Value :=
String(ParamValues[ParamCount].VPWideChar);
else // for other datatypes such as TDate and etc , you can cast it in SQL Server to your own datatype
Parameters.ParamByName(StoredProcedureParams[ParamCount]).Value :=
String(ParamValues[ParamCount].VPWideChar);
end;
end;
ExecProc;
Result := Parameters.ParamValues['@return_value'];
end;
end
else
raise Exception.Create(Format('The Stored Procedure : %s was not found',
[SPName]));
finally
StoredProcedureParams.Free;
end;
end;
نمونه استفاده :
ExecuteStoredProc(ProcName, FetchStoredProcParams(ProcName),
[EmployeeID, FirstName, LastName]);
یا
ExecuteStoredProc(ProcName, 'ID,Fname,LName',
[EmployeeID, FirstName, LastName]);
موفق باشید .