Програмно добавяне на поле в съществуваща TTable

15 отговора 155 прегледа
#1

Програмно добавяне на поле в съществуваща TTable

Как мога програмно да добавя поле към вече съществуваща таблица (Paradox, TTable, Delphi5)?
Опитах с table1.FieldDefs.AddFieldDef, но не става (пък и в Help-а пише, че не става).
Пробвах и table1.fields.add (макар, че пише да не са прави). Пак не става.
А не ми се струва здравословно да дам възможност на клиентите си да бърнират директно в таблиците

Отговор
в отговор на Ada #2

Re: Съжалвяам, сбърках иконката

Съжалвяам, сбърках иконката. Би трябвало да е питанка. Какъв ли медал да дам?

Отговор
в отговор на Ada #3

Re: Програмно добавяне на поле в съществуваща TTab

Ако съм те разбрал правилно искаш да добавиш колона в самата таблица в paradox-а? Най-лено можеш да го направиш с SQL заявка. Сложи си едно Query и му напиши за SQL нещо от сорта на ALTER TABLE [име_на_таблица] ADD [име_на_колона] [тип]. Например:
ALTER TABLE COUNTRY ADD CAPITAL VARCHAR(25)
ALTER TABLE COUNTRY ADD POPULATION INTEGER
После ако си си добавила design time фийловете в таблицата (вече конкретния TTable компонент) ще трябва да си добавиш и новата колона. Ако не си - когато таблицата се отвори ще имаш достъп до колонката.
Надявам се да съм те разбрал правилно! Пиши после дали се е получило! Успех!

Отговор
в отговор на andrew_nikoloff #4

Благодаря

Благодаря, получи се.
Като си помисля колко време се мотах, а като опря ножа до кокала, се справих за 20-тина минути...
SQL не хапел.

Отговор
в отговор на Ada #5

Re: Благодаря

Е, по-добре късно, отколкото никога.
(освен ако dir-а не е объркал пак датите)

Отговор
в отговор на andrew_nikoloff #6

A на тоя диалект на SQL как се разбира дали полето

A на тоя диалект на SQL как се разбира дали полето съществува?
Щото аз си ги добавям рънтайм, но за да ги проверя дали е съществувало си правя заявка със селект (без да връща записи) и гледам дали съществува полето с FieldFind.

Отговор
в отговор на NikB #7

Зависи от базата

Не мисля, че има стандартен начин това да се провери с SQL. А иначе по принцип може, но това зависи от базата, която е отдолу. Например за MS SQL Server има таблици sysobjects и syscolumns, а при Firebird/Interbase има RDB$RELATIONS и RDB$FIELDS. А през API това може да се получи от Database или еквивалентния компонент - например GetFieldNames и GetTableNames на TIBDatabase.

Отговор
в отговор на andrew_nikoloff #8

Да, за MSSQL и MySQL има SQL заявки

Да, за MSSQL и MySQL има SQL заявки.
Но мислех, че има и за парадокс и просто не съм го научил :)

Отговор
в отговор на NikB #9

BDE API

През API-то на BDE трябва да има начин. Просто не го знам обаче. Трябва да се чете как става...

Отговор
в отговор на andrew_nikoloff #10

Няма да е по-лесен от tQuery

Опитът ми показва, че през API на BDE Няма да е по-лесен от tQuery. :)

Отговор
в отговор на NikB #11

Re: A на тоя диалект на SQL как се разбира дали полето

Мога да ти предложа два еднакво тромави (но работещи) начина.

Първи начин:

TForm1 = class(TForm)
Query1: TQuery;
DataSource1: TDataSource;
DBGrid1: TDBGrid;

DataSource1.DataSet = Query1
DBGrid1.DataSource = DataSource1

procedure TForm1.FormCreate(Sender: TObject);
begin
StrList:=TstringList.Create;
Query1.Close;
Query1.Sql.Clear;
Query1.Sql.Add('Select * from парадокската таблица');
Query1.Prepare;
Query1.Open;
StrList.Clear;
for ii:=0 to DBGrid1.Columns.count-1 do
StrList.Add(DBGrid1.Columns[ii].Fieldname);
DBGrid1.visible:=false; // ако пречи
end;

добавяне на поле с име, присвоено на NewFieldName

ii:=0; stop:=false;
while ((ii< StrList.Count) and (not stop)) do
begin
stop:=AnsiSameText(StrList, NewFieldName);
if not stop then inc(ii);
end;
if not stop
then begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('ALTER TABLE парадокската таблица ADD '+ NewFieldName +' integer'); {примерно}
Query1.Prepare;
Query1.ExecSQL;
StrList.Add(Edit2.Text);
Query1.Close;
Query1.Sql.Clear;
Query1.Sql.Add('Select * from парадокската таблица ');
Query1.Prepare;
Query1.Open;
end;

Втори начин:

Имаш
Table1,Table2:TТable
Table1 – таблица, към която трябва да се добавят полета
Table2 – празна таблица с всички необходими полета
Проверява се кои полета от Table2 липсват в Table1 и се добавят.

А има и трети начин: опитваш се да добавиш полетата, ако вече ги има, се получава едно дълго съобщение за грешка, което май няма други лоши последствия, освен стряскане на този, който работи с програмата.

Може да има и други начини, но с моя мижав опит с SQL стигнах до тук.

Отговор
в отговор на Ada #12

Re: A на тоя диалект на SQL как се разбира дали по

Каква е разликата?

Query1.Sql.Clear;
Query1.Sql.Add('Select * from парадокската таблица');

и

Query1.Sql.Text:='Select * from парадокската таблица';


Въпреки, че ако се добави и "where false" ще е малко по-ефективно

Отговор
в отговор на Ada #13

Сега обърнах внимание: FieldDefs.Add

Сега обърнах внимание, че се оплакваш от FieldDefs.Add, а и ми се наложи да добавя едно попе. Може би това е един ефективен начин:


xTable := tTable.Create( Application.MainForm);

xTable.DataBaseName := '';
xTable.TableType := ttParadox;
xTable.TableName := xName; // пълния път до db файла
xTable.FieldDefs.Update; // чете съществуващите филдове
// това е с exception : if xTable.FieldDefs.Find( 'LStateGSM')=nil then begin
{ това не е с exception :Щ if xTable.FieldDefs.IndexOf( 'LStateGSM')>=0 then begin
xTable.FieldDefs.Add( 'LStateGSM', ftInteger, 0, false);
xTable.CreateTable;
end;


Редактирано от NikB на

Отговор
в отговор на NikB #14

Re: Сега обърнах внимание: FieldDefs.Add

Полето се добави, но се изтриха всички записи от xTable.

Отговор
в отговор на Ada #15

Значи FieldDefs.Add работи

Значи FieldDefs.Add работи :)
За триенето - навярно CreateTable го предизвиква.
Много е неприятно.

Отговор
в отговор на NikB #16

Няма пълно щастие

Няма пълно щастие.
Но все пак има решение.

Отговор