2010-02-23 4 views
2

Delphi, похоже, не похож на многополевые индексы.Сортировка таблицы физически в Delphi

Как физически сортировать таблицу так, чтобы я завершался таблицей с строками в нужном порядке?

Пример:

mytable.dbf

Field Field-Name Field-Type Size 
    0  Payer  Character  35 
    1  Payee  Character  35 
    2  PayDate  Date 
    3  Amount  Currency 

мне нужно произвести таблицу отсортированной в алфавитном порядке по "Получателю" + "Плательщик"

Когда я попытался с помощью индекса «Получателя + Плательщик "я получил сообщение об ошибке:

"Field Index out of range"

+0

Я ценю все ответы, которые предлагают различные индексы. Я попробовал их все.
Мой вопрос в том, как легко, физически сортировать таблицу. – ChuckO

+0

Какую библиотеку вы используете для работы с таблицей DBF? –

+0

Я использую BDE – ChuckO

ответ

1

Если вы все еще используете BDE вы можете использовать API BDE физически Отсортируйте DBF таблицы:

uses 
    DbiProcs, DbiTypes, DBIErrs; 

procedure SortTable(Table: TTable; const FieldNums: array of Word; CaseInsensitive: Boolean = False; Descending: Boolean = False); 
var 
    DBHandle: hDBIDb; 
    RecordCount: Integer; 
    Order: SORTOrder; 
begin 
    if Length(FieldNums) = 0 then 
    Exit; 

    Table.Open; 
    RecordCount := Table.RecordCount; 
    if RecordCount = 0 then 
    Exit; 
    DBHandle := Table.DBHandle; 
    Table.Close; 

    if Descending then 
    Order := sortDESCEND 
    else 
    Order := sortASCEND; 

    Check(DbiSortTable(DBHandle, PAnsiChar(Table.TableName), nil, nil, nil, nil, nil, 
    Length(FieldNums), @FieldNums[0], @CaseInsensitive, @Order, nil, False, nil, RecordCount)); 
end; 

, например, в вашем случае:

SortTable(Table1, [2, 1]); // sort by Payee, Payer 
0

не может проверить, но попробовать IndexFieldNames =" PAYEE, Pay эр».
Обязательные индексы по этим двум полям должны существовать.

4

Имена полей индекса должны быть разделены точками с запятой, а не символами плюс. Попробуйте это, и он должен работать.

+0

+1 добрался до меня –

+0

Когда я попытался использовать индекс «Payee; Payer», я получил ошибку: Нет индекса для полей «Payee; Payer» – ChuckO

+2

Что вы используете представить таблицу в Delphi? Я полагаю, вы находитесь в каком-то наборе данных? –

3

Хорошо, попробуем поставить какой-то заказ.

Во-первых, не рекомендуется физически сортировать стол. На самом деле большинство RDBMS даже не предоставляют вам эту функцию. Как правило, один, чтобы не форсировать полное сканирование таблицы (оно называется иногда естественным сканированием) создает индексы в полях таблицы, на которых он считает, что таблица будет сортироваться/искать.

Как вы видите, первым шагом для сортировки таблицы обычно является создание индекса. Это отдельный шаг, это делается один раз, обычно на, скажем, «время разработки». После этого механизм БД позаботится о том, чтобы автоматически обновлять индексы.

Индекс создание сделано Вами (разработчик) с использованием (обычно) не Delphi (или любой другой инструмент разработки), но инструмент администратора вашей RDBMS (тот же самый инструмент, который вы использовали при создании таблицы) ,

Если ваш «БД-движок» - это, по сути, набор данных памяти Delphi (TClientDataSet), то вы перейдете к свойству IndexDefs, откройте его, добавьте новый индекс и установите соответствующие свойства. Интересное свойство в нашем обсуждении - Fields. Установите его на Payee;Payer. Установите также Name, например. "IdxPayee". Если вы используете другого потомка TDataSet, обратитесь к документам вашего механизма БД или задайте еще один вопрос здесь, на SO.com, в котором указаны подробности.

Теперь, чтобы использовать с индексом. (IOW, до сортировка стол, как вы говорите). В вашей программе (либо во время разработки, либо во время выполнения) установите в своей таблице «IndexName» «idxPayee» или любое другое действительное имя, которое вы указали, или установите IndexFieldNames на Payee;Payer.

Обратите внимание еще раз, что приведенный выше пример основан на TClientDataSet. То, что вы должны сохранить из вышеизложенного (если вы его не используете), состоит в том, что вы должны иметь уже созданный индекс, чтобы использовать его.

Кроме того, чтобы ответить на ваш вопрос, да, есть некоторые виды «таблица» (TDataSet потомков в терминологии Delphi), которые поддерживают сортировку, либо с помощью метода Sort (или тому подобное), либо с помощью SortFields собственности.

Но в настоящее время, как правило, при работе с SQL-сервером предпочтительным решением является создание индексов с использованием соответствующего инструмента администрирования, а затем выпуск (с использованием Delphi) SELECT * FROM myTable ORDER BY Field1.

НТН

+0

Стол небольшой, менее 5 тыс. Строк. Данные обрабатываются только один раз, поэтому сортировка является жизнеспособной методологией. Работая в крайний срок, я использовал dBASE для сортировки таблицы. Я буду исследовать метод сортировки TTable. – ChuckO

0

Вы можете создать индекс в своей таблице, используя метод TTable.AddIndex за один вызов. Это будет сортировать ваши данные, когда вы его прочитаете, то есть, если вы используете новый индекс, установив для свойства TTable.IndexName новый индекс. Вот пример:

xTable.AddIndex('NewIndex','Field1;Field2',[ixCaseInsensitive]); 
xTable.IndexName := 'NewIndex'; 
// Read the table from top to bottom 
xTable.First; 
while not xTable.EOF do begin 
    .. 
    xTable.Next; 
end;