Как удалить таблицу?
01.01.2007
Я много работал с клиент-серверным Delphi и MS SQL Server в качестве внутренней базы данных. Операционная модель, которую я использую для своего клиента/сервера, заключается в том, что клиентское приложение действует только как локальный интерфейс, и что все запросы и вычисления - даже временные файлы - выполняются или создаются на сервере. Это создает пару проблем, поскольку очистка мусора не так проста, как при использовании локальных таблиц в качестве временных файлов.
Например, многие из моих программ создают временные файлы, на которые я либо ссылаюсь позже в программе, либо использую в качестве временного хранилища для внешних объединений. Как только я закончу работу с ними, мне нужно будет их удалить. С локальными таблицами это проще простого. Просто получите список таблиц и удалите их с помощью небольшого количества кода, использующего некоторые вызовы Windows API.
Но с таблицами SQL Server не все так просто. Причина в том, что для выполнения задачи вам придется пройти через BDE, а это не обязательно очень интуитивно понятно. К счастью, однако, это не требует низкоуровневых вызовов API BDE.
Ниже приведен список процедур, которые удаляют таблицы из любой базы данных SQL Server. После листинга обсудим детали...
Описание параметров:
//var Ses : TSession; //A valid, open session
//DBName : String; //Name of the SQL Server DB
//ArTables : array of String; //An array of table names
//StatMsg : TStatusMsg); //A status message callback
//procedure
TStatusMsg — процедурный тип, используемый в качестве процедуры обратного вызова.
type
TStatusMsg = procedure(Msg: string);
procedure DropMSSQLTempTables(var Ses: TSession;
DBName: string;
ArTables: array of string;
StatMsg: TStatusMsg);
var
N: Integer;
qry: TQuery;
lst: TStringList;
begin
lst := TStringList.Create;
Ses.GetTableNames(DBName, '', False, False, lst);
try
for N := Low(arTables) to High(arTables) do
if (lst.IndexOf(ArTables[N]) > 0) then
begin
StatMsg('Removing ' + arTables[N] +
' from client database');
qry := TQuery.Create(nil);
with qry do
begin
Active := False;
SessionName := Ses.SessionName;
DatabaseName := DBName;
SQL.Add('DROP TABLE ' + arTables[N]);
try
ExecSQL;
finally
Free;
qry := nil;
end;
end;
end;
finally
lst.Free;
end; { try/finally }
end;
Псевдокод для этого довольно прост.
Получите список всех таблиц в базе данных SQL Server, переданной в процедуру.
Получите имя таблицы из массива имен таблиц.
Если переданное имя таблицы окажется в списке таблиц, полученных из базы данных, УДАЛИТЬ его.
Повторяйте шаги 2 и 3, пока не будут исчерпаны все имена таблиц.
Причина, по которой я провожу сравнение на шаге 3, заключается в том, что если вы выдадите DROP к несуществующей таблице, SQL Server выдаст исключение. Эта методология полностью позволяет избежать этой проблемы.
Ниже приведено подробное описание параметров.
- Ses var TSession
- это переменная экземпляра сеанса, которую вы передаете в процедуру по ссылке.
Примечание.
Перед использованием НЕОБХОДИМО создать экземпляр. Процедура не создает экземпляр. Предполагается, что он уже существует. Это особенно необходимо при использовании этой процедуры внутри потока. Но если вы не создаете многопоточное приложение, вы можете использовать переменную сеанса по умолчанию.
- DBName String
- Имя клиентской базы данных MS SQL Server.
- ArTables Array of String
- это открытый массив строк что вы можете перейти в процедуру. Это означает, что вы можете пройти любой размер массива, и процедура обработает его. Например, в В основной программе создания таблиц я определяю массив следующим образом:
arPat[0] := 'dbo.Temp0';
arPat[1] := 'dbo.Temp1';
arPat[2] := 'dbo.Temp2';
arPat[3] := 'dbo.Temp3';
arPat[4] := 'dbo.Temp4';
arPat[5] := 'dbo.Temp5';
arPat[6] := 'dbo.PatList';
arPat[7] := 'dbo.PatientList';
arPat[8] := 'dbo.EpiList';
arPat[9] := 'dbo.' + FDisease + 'CrossTbl_' + FQtrYr;
arPat[10] := 'dbo.' + FDisease + 'Primary_' + FQtrYr;
и передать его в процедуру.
- StatMsg TStatusMsg
- Это процедурный тип :
procedure(Msg : String). Вы не можете использовать метод класса для этой процедуры; вместо этого вы объявляете обычную процедуру, которая ссылается на обычную процедуру. Например, я объявляю процедуру уровня интерфейса под названием StatMsg, которая ссылается на переменную экземпляра потока и метод следующим образом:
procedure StatMsg(Msg: string);
begin
thr.FStatMsg := Msg;
thr.Synchronize(thr.UpdateStatus);
end;
Хитрость здесь в том, что «thr» — это переменная экземпляра, используемая для создания экземпляра моего класса потока. Переменная экземпляра находится в основной форме моего приложения. Это означает, что его тоже необходимо объявить как переменную интерфейса.
Обычно я не склонен использовать глобальные переменные и процедуры. Это противоречит соглашениям структурного программирования. Однако эта процедура дает мне возможность разместить ее в централизованной библиотеке и использовать во всех моих программах.
Прежде чем использовать это, пожалуйста, обязательно ознакомьтесь с таблицей выше. Вам необходимо объявить тип TStatusMsg до объявления процедуры. Если вы этого не сделаете, вы получите ошибку компиляции.

