📄 database.htm
字号:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<TITLE>UDDF - Databases</TITLE>
</HEAD>
<BODY>
<BODY LINK="#0000ff" VLINK="#800080" BGCOLOR="#ffffff">
<CENTER>
<IMG SRC="../images/uddf.jpg"> </CENTER>
<HR SIZE="6" COLOR="#00FF00">
<FONT FACE="Arial Black" SIZE=7 COLOR="#ff0000"><P ALIGN="CENTER">Database</FONT> </P>
<H1><A NAME="database0">Create a TTable-Component without a form...</A></H1>
<H2> Solution 1</H2>
<I><P>From: gregc@cryptocard.com (Greg Carter)</P>
</I><P>Actually you don't even need to use any component. I pass in nil all the time:</P>
<P><HR></P>
<PRE>FSession := TSession.Create(nil);
FDatabase := TDatabase.Create(nil);
FSession.SessionName := 'DBSession'
FDatabase.Connected := False;
FDatabase.AliasName := Database;
FDatabase.DatabaseName := USER_DATABASE;
FDatabase.SessionName := FSession.SessionName;
FUserTBL := TTable.Create(nil);
FUserTBL.DatabaseName := FDatabase.DatabaseName;
FUserTBL.SessionName := FSession.SessionName;
FUserTBL.TableName := USERTBL;
FUserTBL.IndexName := USERSpIndex;
FUserSource := TDataSource.Create(nil);
FUserSource.DataSet := FUserTBL;</PRE>
<P><HR></P>
<H2>Solution 2</H2>
<I><P>From: William Fisher <wfisher@wpo.borland.com></P>
</I><P>This is some code I had laying around: It worked when I last used it in a larger app.
I don't see anything special I set up in that little app that I neeeded to do differently.
o try something like this. I did this some time ago, I think I decended to add events, but I don't recall... </P>
<P><HR></P>
<PRE>unit Unit2;
interface
uses db, DBTables, dialogs;
type fake = class(Ttable)
procedure fakeFilterRecord(DataSet: TDataSet; var Accept: Boolean);
end;
var
MyTable : fake;
implementation
procedure fake.fakeFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
showmessage('hi Bill');
end;
Initialization
MyTable := fake.create(nil);
With Mytable do begin
DataBaseName := 'dbdemos';
TableName := 'biolife';
OnFilterRecord := MyTable.fakeFilterRecord;
Filtered := true;
active := true;
end;
{just prove I got some data...}
showmessage(MyTable.fields[1].asstring);
Finalization
{important! MyTable has no parent - this will leak memory if you don't free it...}
MyTable.free;
end.</PRE>
<P><HR></P>
<H1><A NAME="database1">Database structure version tracking</A></H1>
<I><P>From: BillRoot@aol.com (Bill Root)</P>
</I><P>Thanks for the ideas, posted here and via email. I think I found a better solution.</P>
<P>Apparently the BDE keeps a structure version number, at least for Paradox files.
(I don't know about dBase or others.) Whenever you change the structure (in Database Desktop, for instance) the
BDE increments the version number. The following unit provides a function that returns the structure database version:</P>
<P><HR></P>
<PRE>(*****************************************************************************
* DbUtils.pas
*
* Database Utilities
*
* 09/20/96 WTR - created
*****************************************************************************)
unit Dbutils;
(****************************************************************************)
(****************************************************************************)
interface
(****************************************************************************)
(****************************************************************************)
uses
DbTables;
function DbGetVersion(table: TTable): LongInt;
(****************************************************************************)
(****************************************************************************)
implementation
(****************************************************************************)
(****************************************************************************)
uses
Db, DbiProcs, DbiTypes, {DbiErrs,}
SysUtils;
{---------------------------------------------------------------------------}
(*
* Purpose: determine the version number of the specified table
* Parameters: table (I) - table of interest
* Returns: version number
* Exceptions: EDatabaseError
*)
function DbGetVersion(table: TTable): LongInt;
var
hCursor : hDBICur;
tableDesc: TBLFullDesc;
cName : array[0..255] of Char;
begin
{ make c-string copy table name }
StrPCopy(cName, table.TableName);
{ ask BDE to create info record for specified table }
Check(DbiOpenTableList(table.DBHandle, True, False, cName, hCursor));
{ get info record into structure }
Check(DbiGetNextRecord(hCursor, dbiNOLOCK, @tableDesc, nil));
{ get version field from extended portion }
Result := tableDesc.tblExt.iRestrVersion;
Check(DbiCloseCursor(hCursor));
end;
end.</PRE>
<P><HR></P>
<H1><A NAME="database2">Lookup value on input</A></H1>
<I><P>From: Alain Toutant <a.toutant@sympatico.ca</P>
</I><PRE>Dirk Couck wrote:
>
How can I lookup a value in a table or query while the user is typing in . The cursor (and
display) should be closer to the exact value as the user puts in more characters.
>
</PRE>
<P>I did something like this in delphi 1. It might not be the best solution but it works.</P>
<P>I Keep a TTable open for the value to be searched for.
The index must, of course, be on the field that's used in the edit box.
In the editbox's change event I use the editbox's value in a FindNearest call on the TTable. Whatever I get as a result is placed back in the editbox's text.</P>
<P>This is only the general way of it. In fact I enable a 1/3 second timer in the change event and do the search
(and disable the timer) in the timer's timer event. This allows the user to type rapidely without having to do the search for every character typed.</P>
<P>You may also want to do some special processing for the backspace key or force the selection to the added part of the string.</P>
<I><P>From: "Paul Motyer" <paulm@linusserver.pccity.com.au></P>
</I><P>Instead of returning the results to the edit box (which would overwrite the end-user's entry) display the results in
something else - eg a listbox. You could display several near matches this way eg:</P>
<P><HR></P>
<PRE>procedure Edit1OnChange( ...);
var i:integer;
begin
if not updating then exit; {set updating elsewhere - eg a timer}
updating:= false;
Table1.FindNearest([Edit1.text]);
ListBox1.clear;
i:= 0;
while (i < 5) and (not (table1.eof)) do
begin
listbox.items.add(Table1.fields[0].asString);
inc(i);
table1.next;
end;
listbox1.itemindex:= 0;
end;</PRE>
<P><HR></P>
<H1><A NAME="database3">DbiCopyTable example</A></H1>
<I><P>From: "David S. Becker" <dsb@plaza.ds.adp.com></P>
</I><P>Here is an example of a routine that I use for copying and deleting tables.
It uses DB, DBTables, DbiProcs,DbiErrs, and DbiTypes.
You simply provide the directory to copy from, the source table name, the directory to copy to,
and the destination table name, and the BDE will copy the entire table, indexes and all to the new file.
The delete function takes the path to delete from and the name of the table to delete, the BDE takes care
of deleting all associated files (indexes, etc.). These procedures have been pulled off a form of mine,
and I've edited them to remove some dependencies that existed with that form.
They should now be completely stand-alone. (If they compile, that is! :) Use in good health, and enjoy!</P>
<P><HR></P>
<PRE>procedure TConvertForm.CopyTable(FromDir, SrcTblName, ToDir, DestTblName: String);
var
DBHandle: HDBIDB;
ResultCode: DBIResult;
Src, Dest, Err: Array[0..255] of Char;
SrcTbl, DestTbl: TTable;
begin
SrcTbl := TTable.Create(Application);
DestTbl := TTable.Create(Application);
try
SrcTbl.DatabaseName := FromDir;
SrcTbl.TableName := SrcTblName;
SrcTbl.Open;
DBHandle := SrcTbl.DBHandle;
SrcTbl.Close;
ResultCode := DbiCopyTable(DBHandle,false,
StrPCopy(Src,FromDir + '\' + SrcTblName),nil,
StrPCopy(Dest,ToDir + '\' + DestTblName));
if (ResultCode <> DBIERR_NONE) then
begin
DbiGetErrorString(ResultCode,Err);
raise EDatabaseError.Create('While copying ' +
FromDir + '\' + SrcTblName + ' to ' +
ToDir + '\' + DestTblName + ', the '
+ ' database engine generated the error '''
+ StrPas(Err) + '''');
end;
finally
SrcTbl.Free;
DestTbl.Free;
end;
end;
procedure TConvertForm.DeleteTable(Dir, TblName: String);
var
DBHandle: HDBIDB;
ResultCode: DBIResult;
tbl, Err: Array[0..255] of Char;
SrcTbl, DestTbl: TTable;
SrcTbl := TTable.Create(Application);
try
SrcTbl.DatabaseName := Dir;
SrcTbl.TableName := TblName;
SrcTbl.Open;
DBHandle := SrcTbl.DBHandle;
SrcTbl.Close;
ResultCode := DbiDeleteTable(DBHandle,
StrPCopy(Tbl,Dir + '\' + TblName),nil);
if (ResultCode <> DBIERR_NONE) then
begin
DbiGetErrorString(ResultCode,Err);
raise EDatabaseError.Create('While deleting ' +
Dir + '\' + TblName + ', the database ' +
'engine generated the error '''
+ StrPas(Err) + '''');
end;
finally
SrcTbl.Free;
end;
end;</PRE>
<P><HR></P>
<H1><A NAME="database4">Problem with "Getting Started" Guide P 42</A></H1>
<I><P>From: jays@weldnet.com (Jay Schwisow)</P>
</I><PRE>In article <a67cc$12c21.16d@news.vortex.is>, From siggir@vortex.is
(Sigurdur Reynisson), the following was written:
> I just installed Delphi 2.0 and it went just fine, no comment's or remarks came from the
installation process.
>
> I'm going through the "getting started" guide for Delphi 2.0. On page 42, "Adding a
display grid" for the DBGrid, having set the DataSource to
GDSDataModule.CustomerSource, I get no data in the DBGrid. At the bottom of page
42 it simply states "Immediately, the data is displayed in the DBGrid." but that never
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -