Делу время, а потехе час. Это я к тому, что помимо исследований Delphi для Android (а вы уже тестируете бету?) есть работа, которую нужно делать. За сим, очередной пост-шпаргалка, возможно, кому-нибудь пригодится.
В коде моих проектов имеется множество функций, подобных, приведенной ниже.
function TFMain.ExtDescrExists(): Boolean; var qry: TADOQuery; begin Result:= True; try qry:= TADOQuery.Create(Self); qry.Connection:= DM.cnDatabase; qry.SQL.Add('SELECT ExpenseID FROM tblProjectExpenses WHERE ExpenseDescription<>NULL'); qry.Open; if qry.IsEmpty then begin Result:= False; end; qry.Close; finally FreeAndNil(qry); end; end;
Откровенно говоря, подобный код мне не особо нравится, прежде всего из-за громоздкости. Обратите внимание на рисунок:
Необходимость повторного использования кода в данном случае очевидна. Однако, сделать универсальное решение не совсем просто, поскольку в некоторых случаях проверяется наличие записей в таблице, в других – требуется извлечь значения различных типов. Чтобы решить эту задачу, я набросал небольшой класс:
unit uATRQueries; interface uses ADODB, ADOInt, StrUtils, Dialogs, SysUtils, DB; type TATRQuery = class strict private class var FConnection: TADOConnection; private class function GetDataBase: TADOConnection; static; class procedure SetDataBase(const Value: TADOConnection); static; public class function ExecSQL(aSQL: string): Boolean; class function GetRecCountBySQL(aSQL: string): integer; class function FieldValIsNULL(aSQL, aFieldName: string): Boolean; class function GetIntFieldBySQLDef(aSQL, aFieldName: string; def: Integer = 0; ShowEmptyMessage: Boolean = False; EmptyMessage: string = 'There are no records.'): integer; class function GetDataSet(aSQL: string): TDataSet; class property DataBase: TADOConnection read GetDataBase write SetDataBase; end; implementation uses uDM; { TATRQuery } class function TATRQuery.GetDataBase: TADOConnection; begin Result:= FConnection; end; class function TATRQuery.GetDataSet(aSQL: string): TDataSet; var Qry: TADOQuery; begin try Qry:= TADOQuery.Create(DM); qry.Connection:= FConnection; qry.SQL.Add(aSQL); qry.Open; Result:= qry as TDataSet; finally end; end; class function TATRQuery.GetIntFieldBySQLDef(aSQL, aFieldName: string; def: Integer; ShowEmptyMessage: Boolean; EmptyMessage: string): integer; var Qry: TADOQuery; begin try Result:= Def; Qry:= TADOQuery.Create(DM); qry.Connection:= FConnection; qry.SQL.Add(aSQL); qry.Open; if Qry.IsEmpty then begin if ShowEmptyMessage then MessageDlg(EmptyMessage, mtWarning, [mbOK], 0); Exit; end; Result:= Qry.FieldByName(aFieldName).AsInteger; finally FreeAndNil(Qry); end; end; class function TATRQuery.GetRecCountBySQL(aSQL: string): integer; var Qry: TADOQuery; begin try Result:= -1; Qry:= TADOQuery.Create(DM); qry.Connection:= FConnection; qry.SQL.Add(aSQL); qry.Open; Result:= qry.RecordCount; finally FreeAndNil(Qry); end; end; class function TATRQuery.ExecSQL(aSQL: string): Boolean; var Qry: TADOQuery; begin Result:= True; try Qry:= TADOQuery.Create(DM); qry.Connection:= FConnection; qry.SQL.Add(aSQL); try qry.ExecSQL; except Result:= False; end; finally FreeAndNil(Qry); end; end; class function TATRQuery.FieldValIsNULL(aSQL, aFieldName: string): Boolean; var Qry: TADOQuery; begin try Result:= False; Qry:= TADOQuery.Create(DM); qry.Connection:= FConnection; qry.SQL.Add(aSQL); qry.Open; Result:= Qry.FieldByName(aFieldName).IsNull; finally FreeAndNil(Qry); end end; class procedure TATRQuery.SetDataBase(const Value: TADOConnection); begin if Assigned(Value) then FConnection:= Value; end; end.
Практически все методы, являются методами класса. Соответственно, использовать класс можно примерно так:
TATRQuery.DataBase:= DM.cnDatabase; NeedCompany:= TATRQuery.FieldValIsNULL('SELECT dCompanyID FROM tblEmployees WHERE EmployeeID = '+IntToStr(aEmployeeID) , 'dCompanyID');
Как говорится, почувствуйте разницу!
Естественно, по мере необходимости функциональность класса может расширяться.
Здравствуйте
А как с параметрами работать при инсерте итд
Я параметры не использую. В смысле, я их переда. непосредственно в SQL.
Например,
TATRQuery.FieldValIsNULL(‘SELECT dCompanyID FROM tblEmployees WHERE EmployeeID = ‘+IntToStr(aEmployeeID) , ‘dCompanyID’);
Вместо того, что бы передать значение aEmployeeID в качестве параметра. Но в принципе, Вы правы. Нужно подумать над тем, как передать параметры.
Хотя, как по мне, это будет немного сложнее. Поскольку вместе со значением параметра нужно будет обозначать его тип и т.д.
В типах и есть прелесть параметров – не надо морочить голову с порядком цифр в датах, не надо мучиться с кавычками для стрингов…
Жду реализация с параметрами желаю удачи
Подскажите, а где тут выбор самой БД? С MS SQL можно работать?
class property DataBase: TADOConnection read GetDataBase write SetDataBase;
Вы любой настроенный ADOConnection цеплятете.
Примерно так:
TATRQuery.DataBase:= DM.cnDatabase;
Где DM.cnDatabase настроен руками и, собственно, работает.
Естественно, с MS SQL это будет работать. В принципе, вместо ADODB вы можете переделать класс под любую библиотеку доступа к данным.
FireDAC, UniDAC, FIB, IBExpress, что угодно… Базовые классы и методы однотипны.
Я наверное неправильно задал вопрос. Просто уже умучался искать ответ.
Среда – delphi xe5
пробую написать на андройде запрос к MS SQL. У FireDac нельзя выбрать MS SQL.
Что посоветуете?