![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
addindex, детский вопрос
Evgeny © (2003-04-29 12:41:00)Вопрос то, конечно детский, но почему при вызове:
Table.AddIndex("part_numbe", "part_numbe", [ixExpression]);
выскакивает ошибкаInvalid index descriptor? Таблица в формате DBase.
Evgeny (2003-04-30 14:14:00) [1]Но есть еще одна проблема. Я пытался создать поле типа Integer с параметрами
Add("field2", ftInteger, 0, False);
но в оригинальной таблице, как я уже указывал, установлено 20, 5. Как такое поле можно создать?
Anatoly Podgoretsky (2003-04-30 13:53:00) [2]SUBSTR(C,100) кажется так, подробности смотреть в документации по базе данные. Ранее немного было в Дельфи, список поддерживаемых функций, это вроде бы поддеживаемая.
Evgeny (2003-04-30 13:43:00) [3]Таблица не моя она поставляется изготовителем и обновляется почти каждую неделю. Я не знал что длина полей может вызвать такую ошибку. А поля в базе такие:
С 120
С 200
N 20, 5
в любом случае первое поле мне нужно индексировать, а значит его придется усекать. Я пытался создать таблицу с усеченными полями, но столкнулся с тем, что не получилось создать 3 поле. Справка меня опять ничем толковым не просветила.
Anatoly Podgoretsky (2003-04-30 13:32:00) [4]Evgeny © (30.04.03 11:50)
Database Desktop это делает миную БДЕ и такая таблица наверняка работает неверно, например обрезает индекс.
Индексы по строковым полям свыше 30-60 это как то попахивает мазохизмом.
Ты бы сразу имел ответ о проблеме, если бы привел необходимые данные, тип базы, структура, индекс, вместо того что бы из тебя это вытягивать по кусочкам
Evgeny (2003-04-30 11:50:00) [5]Max. # of chars per index key (IDX) 100
Возможно MDX придерживается того же правила, но Database Desktop это все же спокойно проделывает. Сейчас хочу попробовать на низком уровне DbiAddIndex, может эта функция поможет.
Anatoly Podgoretsky (2003-04-30 10:29:00) [6]Вот ограничения для FoxPro, для DBase 4 тоже самое
FoxPro limits
Table and Index Files
Max. # of records per table 1 billion*
Max. # of chars per record 65,000
Max. # of fields per record 255
Max. # of open DBFs 225
Max. # of chars per field 254
Max. # of chars per index key (IDX) 100
Max. # of chars per index key (CDX) 240
Max. # of open index files per table unlimited**
Max. # of open index files in all work areas unlimited**
Anatoly Podgoretsky (2003-04-30 10:22:00) [7]Evgeny © (30.04.03 09:39)
Насколько я помню, это ограничение формата.
Evgeny (2003-04-30 09:39:00) [8]Причину обнаружить удалось. Все дело в том, что если любое из строковых полей превышает длину в 100 символов тогда и выскакивает ошибка
Invalid index descriptor. Какой то бред Database Desktop в то же время спокойно добавляет индексы. Как все же решить проблему?
Evgeny (2003-04-30 09:10:00) [9]Подскажите все же где глюк. Этот вариант работает:
procedure CreateTbl2;
var
TableName : String;
FaqTable : TTable;
Dir : String;
begin
FaqTable := TTable.Create(NIL);
FaqTable.Close;
TableName := "test.dbf";
Dir := ExtractFileDir(ParamStr(0));
if FileExists(TableName) then
begin
WriteLn(TableName + " уже существует");
Exit;
end;
FaqTable.DatabaseName := Dir + "\";
FaqTable.TableType := ttDbase;
FaqTable.TableName := TableName;
FaqTable.FieldDefs.Add("DATE", ftString, 20, False);
FaqTable.FieldDefs.Add("ID", ftString, 20, False);
FaqTable.FieldDefs.Add("KEYWORD", ftString, 20, False);
FaqTable.FieldDefs.Add("QUESTION", ftString, 20, False);
FaqTable.CreateTable;
FaqTable.AddIndex("ID","ID",[]);
FaqTable.AddIndex("DATE","DATE",[]);
FaqTable.AddIndex("KEYWORD","upper(KEYWORD)",[ixExpression]);
FaqTable.AddIndex("QUESTION","upper(QUESTION)",[ixExpression]);
FaqTable.IndexName := "ID";
FaqTable.Open;
WriteLn("Создана новая таблица: " + FaqTable.TableName);
end;
а этот ни в какую не желает:
procedure CreateTbl1;
begin
Name := "bym.dbf";
Dir := ExtractFileDir(ParamStr(0));
if FileExists(Name + ".org") then
begin
WriteLn(#13#10#9"Ранее уже было произведено преобразование таблиц!");
Exit;
end;
LocTbl := TTable.Create(NIL);
try
if not CopyFile(PChar(Name), PChar(Name + ".org"), True) then
begin
WriteLn("Не удалось создать резервную копию файла " + Name);
Exit;
end;
LocTbl.DatabaseName := Dir + "\";
LocTbl.TableName := Name;
LocTbl.TableType := ttDBase;
LocTbl.Exclusive := True;
LocTbl.Close;
LocTbl.AddIndex("PART_NUMBE", "PART_NUMBE", []);
finally
LocTbl.Close;
LocTbl.Free;
end;
end;
Evgeny (2003-04-30 08:16:00) [10]>Anatoly Podgoretsky © (29.04.03 13:39)
Немного подправил под себя ваш вариант, для теста. Результат печальный, единственная разница, моя программа консольная.
procedure CreateTbl2;
var
TableName : String;
FaqTable : TTable;
Dir : String;
begin
FaqTable := TTable.Create(NIL);
FaqTable.Close;
TableName := "test.dbf";
Dir := ExtractFileDir(ParamStr(0));
if FileExists(TableName) then
begin
WriteLn(TableName + " уже существует");
Exit;
end;
FaqTable.DatabaseName := Dir + "\";
FaqTable.TableType := ttDbase;
FaqTable.TableName := TableName;
FaqTable.CreateTable;
FaqTable.AddIndex("ID","ID",[]);
FaqTable.AddIndex("DATE","DATE",[]);
FaqTable.AddIndex("KEYWORD","upper(KEYWORD)",[ixExpression]);
FaqTable.AddIndex("QUESTION","upper(QUESTION)",[ixExpression]);
FaqTable.IndexName := "ID";
FaqTable.Open;
WriteLn("Создана новая таблица: " + FaqTable.TableName);
end;
Evgeny (2003-04-29 13:49:00) [11]Вот полный код:
procedure ConvertTable;
var
I : Integer;
LocTbl: TTable;
function CheckOpenTable(Name : String) : Boolean;
begin
Result := False;
LocTbl.DatabaseName := Dir + "\";
LocTbl.TableName := Name;
LocTbl.TableType := ttDBase;
LocTbl.Active := True;
if (LocTbl.Fields.Count = 3) and
((LocTbl.Fields.Fields[0].DataType = ftString) and (LowerCase(LocTbl.Fields.Fields[0].FieldName) = "part_numbe")) and
((LocTbl.Fields.Fields[1].DataType = ftString) and (LowerCase(LocTbl.Fields.Fields[1].FieldName) = "field2")) and
((LocTbl.Fields.Fields[2].DataType = ftFloat) and (LowerCase(LocTbl.Fields.Fields[2].FieldName) = "field3")) then
Result := True;
LocTbl.Active := False;
end;
procedure CreateBackupTable(Name : String);
var
S, St : String;
I, J : Integer;
Rec : Integer;
Procent : String;
begin
if not CopyFile(PChar(Name), PChar(Name + ".org"), True) then
begin
Log.Add("Не удалось создать резервную копию файла " + Name);
Exit;
end;
St := #9"Обрабатывем таблицу: " + Name;
Write(St);
Log.Add(St);
LocTbl.AddIndex("part_numbe", "part_numbe", []);
LocTbl.Active := True;
....
LocTbl.Active := False;
....
end;
begin
LocTbl := TTable.Create(NIL);
try
for I := 0 to 1 do //List.Count - 1 do
begin
if CheckOpenTable(List.Strings[I]) then
CreateBackupTable(List.Strings[I])
else
Log.Add("Файл " + "_" + List.Strings[I] + " не создался.");
end;
finally
LocTbl.Close;
LocTbl.Free;
end;
end;
Evgeny (2003-04-29 13:46:00) [12]>Anatoly Podgoretsky © (29.04.03 13:39)
Честно говоря, не вижу особой разницы, только что у меня таблица уже существует.
Anatoly Podgoretsky (2003-04-29 13:44:00) [13]Evgeny © (29.04.03 13:32)
DBase 4 не поддерживает первичных ключей, так что это строка тоже не верна.
Evgeny (2003-04-29 13:41:00) [14]У меня непосредственно при выполнении AddIndex, таблица также не активна, да мой код приведен чуть выше.
Anatoly Podgoretsky (2003-04-29 13:39:00) [15]Table.AddIndex("part_numbe", "part_numbe", []);
Я использую этот вариант, ни разу не подводил
Table.AddIndex("part_numbe", "part_numbe", []);
Вот полностью рабочий код
procedure TFaqCreateForm.OkButtonClick(Sender: TObject);
var
TableName : string;
begin
DM.FaqTable.Close;
TableName := RootPath + BaseNameEdit.Text;
if Pos(".dbf",TableName) = 0 then begin
TableName := TableName + ".dbf";
end;
if FileExists(TableName) then begin
ShowMessage(TableName + " уже существует");
ModalResult := mrNone;
exit
end;
DM.FaqTable.TableType := ttDbase;
DM.FaqTable.TableName := ExtractFilename(TableName);
DM.FaqTable.CreateTable;
DM.FaqTable.AddIndex("ID","ID",[]);
DM.FaqTable.AddIndex("DATE","DATE",[]);
DM.FaqTable.AddIndex("KEYWORD","upper(KEYWORD)",[ixExpression]);
DM.FaqTable.AddIndex("QUESTION","upper(QUESTION)",[ixExpression]);
DM.FaqTable.IndexName := "ID";
DM.FaqTable.Open;
ShowMessage("Создана новая таблица: " + DM.FaqTable.TableName);
end;
DBase IV
Соловьев (2003-04-29 13:35:00) [16]
> У тебя DBase VII или старше
да, а как это влияет? я не спорю, просто интересно.
> Evgeny © (29.04.03 13:25)
у меня таблица Active = false;
Evgeny (2003-04-29 13:32:00) [17]DBase у меня 4, и если открывать в ДОСе, то я открываю ее программой DBU. данная строка:
LocTbl.AddIndex("part_numbe", "part_numbe", [ixPrimary]);
также не прошла.
Evgeny (2003-04-29 13:25:00) [18]>Anatoly Podgoretsky © (29.04.03 13:17)
Если не трудно, будь добр приведи вариант, который не вызовет указанную ошибку.
Мой вариант был таков:
Table := TTable.Create(NIL);
Table.DatabaseName := Dir + "\";
Table.TableName := Name;
Table.TableType := ttDBase;
Table.Active := False;
Table.Exclusive := True;
Table.AddIndex("part_numbe", "part_numbe", []);
Table.Active := True;
Что я не нашел в справке, так это должна ли таблица при добавлении индекса быть активной или нет. Поиск по интернету меня также не просветил, встречаются различные варианты. Также очень много встречается именно точно таких же вопросов и НИ ОДНОГОответа.
Anatoly Podgoretsky (2003-04-29 13:24:00) [19]Да если ты считаешь, сказав DBaseты все сказал, то ты ошибаешься.
Соловьев © (29.04.03 13:19)
У тебя DBase VII или старше
Соловьев (2003-04-29 13:19:00) [20]
> Evgeny © (29.04.03 13:08)
у меня
...
table1.AddIndex("t1","cod",[ixPrimary]);
...
сработал без всяких траблов. файл получился table.mdx
Может после твоих изысканий уже таблица попорченная. В досовском Fox открывается?