Wenn Sie eine Datenbankklasse wie abgebildet verwenden möchten, sollten Sie die Fähigkeit von Datensätzen berücksichtigen, Funktionen in D2007 und höher zu enthalten.
Zum Beispiel Ihr Beispiel würde:
type
TUserTable = record
TableName : String;
Username : String;
Password : String;
function sqlGetUserName(where:string=''):string;
end;
const
UserTable : TUserTable =
(
TableName : 'users';
Username : 'Username';
Password : 'Password';
);
function TUserTable.sqlGetUserName(where:string=''): string;
begin
if where='' then result := Format('SELECT %s from %s', [userName, tableName])
else result := Format('SELECT %s from %s where %s', [userName, tableName, where]);
end;
, die erlaubt:
query.SQL.add(userTable.sqlGetUserName);
oder
query.SQL.add(userTable.sqlGetUserName(Format('%s=%s', [userTable.userName,'BOB']));
ich wirklich nicht empfehlen mit SQL direkt, wie Sie haben illustriert. Meiner Meinung nach sollten Sie niemals direkte SQL-Aufrufe an die Tabellen haben. Das führt zu einer starken Kopplung zwischen der Benutzeroberfläche und der Datenbank (die nicht existieren sollte) und verhindert, dass Sie eine hohe Sicherheitsstufe für die direkte Tabellenmodifikation festlegen.
Ich würde alles in gespeicherte Procs einbinden und eine DB-Interface-Klasse haben, die den gesamten Datenbankcode in ein Datenmodul kapselt. Sie können die direkten Links zu datensensitiven Komponenten weiterhin von einem Datenmodul aus verwenden, Sie müssen lediglich die Links mit dem DM-Namen voranstellen.
Zum Beispiel, wenn Sie eine Klasse wie gebaut:
type
TDBInterface = class
private
function q(s:string):string; //just returns a SQL quoted string
public
procedure addUser(userName:string; password:string);
procedure getUser(userName:string);
procedure delUser(userName:string);
function testUser:boolean;
procedure testAllDataSets;
end;
function TDBInterface.q(s:string):string;
begin
result:=''''+s+'''';
end;
procedure TDBInterface.addUser(userName:string; password:string);
begin
cmd.CommandText:=Format('if (select count(userName) from users where userName=%s)=0 '+
'insert into users (userName, password) values (%s,%s) '+
'else '+
'update users set userName=%s, password=%s where userName=%s',
[q(userName), q(userName), q(password), q(userName), q(password), q(userName)]);
cmd.Execute;
end;
procedure TDBInterface.getUser(userName:string);
begin
qry.SQL.Add(Format('select * from users where userName=%s', [q(userName)]));
qry.Active:=true;
end;
procedure TDBInterface.delUser(userName:string);
begin
cmd.CommandText:=Format('delete from users where userName=%s',[userName]);
cmd.Execute;
end;
procedure TDBInterface.testAllDataSets;
begin
assert(testUser);
end;
function TDBInterface.testUser: boolean;
begin
result:=false;
addUser('99TEST99','just a test');
getUser('99TEST99');
if qry.IsEmpty then exit;
if qry.FieldByName('userName').value<>'99TEST99' then
exit;
delUser('99TEST99');
if qry.IsEmpty then
result:=true;
end;
Sie haben jetzt die Möglichkeit, eine Form von Unit-Tests auf Ihrer Datenschnittstelle zu tun, haben Sie die SQL von der Benutzeroberfläche entfernt und die Dinge sind hoch schauen. Sie haben noch eine Menge hässliche SQL in Ihrem Code-Schnittstelle, obwohl, so dass über gespeicherte Procs bewegen und Sie erhalten:
type
TDBInterface = class
public
procedure addUser(userName:string; password:string);
procedure getUser(userName:string);
procedure delUser(userName:string);
function testUser:boolean;
procedure testAllDataSets;
end;
procedure TDBInterface.addUser(userName:string; password:string);
begin
cmd.CommandText:='usp_addUser;1';
cmd.Parameters.Refresh;
cmd.Parameters.ParamByName('@userName').Value:=userName;
cmd.Parameters.ParamByName('@password').Value:=password;
cmd.Execute;
cmd.Execute;
end;
procedure TDBInterface.getUser(userName:string);
begin
sproc.Parameters.ParamByName('@userName').Value:=userName;
sproc.Active:=true;
end;
procedure TDBInterface.delUser(userName:string);
begin
cmd.CommandText:='usp_delUser;1';
cmd.Parameters.Refresh;
cmd.Parameters.ParamByName('@userName').Value:=userName;
cmd.Execute;
end;
Sie nun einige dieser Funktionen in einem ADO-Thema und die UI würde keine Ahnung haben, bewegen konnte Das Hinzufügen oder Löschen von Benutzern erfolgt in einem separaten Prozess. Beachten Sie, dass dies sehr einfache Operationen sind. Wenn Sie also nützliche Dinge tun möchten, wie das Benachrichtigen des übergeordneten Elements, wenn der Prozess abgeschlossen ist (um beispielsweise nach dem Hinzufügen/Löschen/Aktualisieren eine Benutzerliste zu aktualisieren), müssen Sie dies in das Threading einprogrammieren Modell.
die gespeicherte Prozedur für das Add-Code BTW, wie folgt aussieht:
create procedure [dbo].[usp_addUser](@userName varchar(20), @password varchar(20)) as
if (select count(userName) from users where [email protected])=0
insert into users (userName, password) values (@userName,@password)
else
update users set [email protected], [email protected] where [email protected]
Auch ein wenig Haftungsausschluss: Dieser Beitrag ziemlich lang ist und, während ich versuchte, die meisten davon zu überprüfen, habe ich etwas verpasst haben Irgendwo.
Suche nach dem Artikel Analysieren von DataSets (in Delphi und Kylix). Verwenden Sie den Code dort, um eine Generatorart der Anwendung zu schreiben. – user114285