Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Adox. Проблема с индексами.

3.0K
20 января 2005 года
crujer
20 / / 29.01.2004
Пишу прогу с использованием ADOX. Имеется таблица, в ней нужно програмно добавить несколько индексов. Один добавляет, а дальше прога ругается, что такой объект уже существует и больше добавлять не хочет.
пример кода:
For x = 0 To 5
Set MyInd = New adox.Index
MyInd.Name = NamesArr(x)
MyInd.Columns.Append NamesArr(x)
MyDB.Tables("main").Indexes.Append MyInd
Next
----------------------------------------
NamesArr, соответственно - массив с 6 именами полей. Все названия полей - из одного слова, латинские буквы, максимальная длина - 5 символов. Как проблему решить? Заранее благодарен.
4.4K
21 января 2005 года
blind rain
66 / / 20.07.2004
А что через менеджера к Вашей БД видать? - может действительно есть такие индексы?
Проверьте содержимое массива NamesArr - возможно в результате другой ошибки в нем есть повторяющиеся имена?
Попробуйте для имен индексов дать префикс какой-нибудь (типа ndx), возможно есть особенности именования объектов в БД, которую Вы используете.
Я проверил Ваш код для MS Access 2000 - замечательно работает.
Код:
Private Sub Command1_Click()
    Dim DB As ADOX.Catalog
    Set DB = New ADOX.Catalog
    call DB.Create ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Temp\test1.mdb")
    Dim TBl As ADOX.Table
    Set TBl = New ADOX.Table
    TBl.Name = "main"
    TBl.Columns.Append "ID", adInteger
    TBl.Columns.Append "Name", adVarWChar, 50
    TBl.Columns.Append "Nik", adVarWChar, 10
    Set TBl.ParentCatalog = DB
    DB.Tables.Append TBl
   
    Set TBl = DB.Tables("main")
    Dim MyInd As ADOX.Index
    Dim NamesArr() As String
    ReDim NamesArr(0 To TBl.Columns.Count - 1) As String
    Dim x As Long
    For x = 0 To TBl.Columns.Count - 1
        NamesArr(x) = TBl.Columns(x).Name
    Next x
   
    For x = LBound(NamesArr) To UBound(NamesArr)
        Set MyInd = New ADOX.Index
        MyInd.Name = NamesArr(x)
        MyInd.Columns.Append NamesArr(x)
        TBl.Indexes.Append MyInd
    Next
    Set TBl = Nothing
    Set DB = Nothing
End Sub
3.0K
28 января 2005 года
crujer
20 / / 29.01.2004
Да, действительно, так работает.
На самом деле, приведённый код был упрощённым. Названия базы, таблиц и полей, а так же свойства полей беруться из хml-файла.

Неработавший код выглядел так:
[COLOR=blue]
For FCo = 1 To MyXml.documentElement.childNodes.Item(TCo).childNodes.length - 1
Select Case LCase(MyNode.getAttribute("key"))
Case "pk"
Set MyInd = New adox.Index
MyInd.Name = MyXml.documentElement.childNodes.Item(TCo).childNodes.Item(FCo).childNodes.Item(0).Text
MyInd.PrimaryKey = True
MyInd.Unique = True
Case "indx"
Set MyInd = New adox.Index
MyInd.Name = MyXml.documentElement.childNodes.Item(TCo).childNodes.Item(FCo).childNodes.Item(0).Text
End Select
MyInd.Columns.Append MyXml.documentElement.childNodes.Item(TCo).childNodes.Item(FCo).childNodes.Item(0).Text
MyTable.Indexes.Append MyInd
Next
[/COLOR]

А работающий (теперь) код выглядит так:
[COLOR=blue]
For FCo = 1 To MyXml.documentElement.childNodes.Item(TCo).childNodes.length - 1
Set MyNode = MyXml.documentElement.childNodes.Item(TCo).childNodes.Item(FCo)
If LCase(MyNode.getAttribute("key")) = "indx" Then
Set MyInd = New adox.Index
MyInd.Name = MyXml.documentElement.childNodes.Item(TCo).childNodes.Item(FCo).childNodes.Item(0).Text
MyInd.Columns.Append MyXml.documentElement.childNodes.Item(TCo).childNodes.Item(FCo).childNodes.Item(0).Text
MyTable.Indexes.Append MyInd
Else
If LCase(MyNode.getAttribute("key")) = "pk" Then
Set MyInd = New adox.Index
MyInd.Name = MyXml.documentElement.childNodes.Item(TCo).childNodes.Item(FCo).childNodes.Item(0).Text
MyInd.PrimaryKey = True
MyInd.Unique = True
MyInd.Columns.Append MyXml.documentElement.childNodes.Item(TCo).childNodes.Item(FCo).childNodes.Item(0).Text
MyTable.Indexes.Append MyInd
End If
End If
Next
[/COLOR]
То бишь, после замены конструкции Select Case ... на конструкцию If... Then... Else... всё заработало. Почему - не понимаю. Может, объяснит кто?
Цитата:
И моя благодарность не будет иметь границ в пределах разумного

:))))
И ещё. Теперь возникает такая проблема - если два и больше индексов в таблице помещаются, то вот два первичных ключа никак не хотят вставляться. То есть, первый вставляется, а второй - не хочет. Вылезает ошибка, и выполнение проги останавливается. Хелп, плз.

Некоторые пояснения по проге.
XML-файл имеет примерно следующую структуру:
[COLOR=darkblue]
<db>MyDatabase.mdb
<table>Orders
<field key="pk" type="number">ID</field>
<field key="indx" type="text">ProductName</field>
<field type="number">clientID</field>
</table>
<table>Clients
<field key="pk" type="number">ID_Cl</field>
<field type="text">Cl_Name</field>
</table>
</db>
[/COLOR]

FCo - счётчик, соответствующий порядку обрабатываемого поля.
TCo - счётчик, соответствующий порядку обрабатываемой таблицы. Здесь цикл с обработкой таблицы не показан, цикл обработки поля вложен в цикл обработки таблицы.
Заренее благодарен.

258
28 января 2005 года
SergeySV
1.5K / / 19.03.2003
Так как же у тебя будет два первичных ключа? на то он и первичный, чтобы одному быть... может тебе нужен первичный ключ составной? чтобы из нескольких индексов состоял
3.0K
31 января 2005 года
crujer
20 / / 29.01.2004
Цитата:
Originally posted by SergeySV
Так как же у тебя будет два первичных ключа? на то он и первичный, чтобы одному быть... может тебе нужен первичный ключ составной? чтобы из нескольких индексов состоял


Ну да, составной собственно и имелся ввиду.

258
07 февраля 2005 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by crujer

Ну да, составной собственно и имелся ввиду.



Так, ну значит:

Код:
' Создаем новый объект индекса
Set idx = New ADOX.Index
idx.Name = "мойпервичныйключ"

' Сделаем новый индекс первичным ключом
idx.PrimaryKey = True
idx.Unique = True

' Теперь создадим индексированные столбцы
' и добавим их в коллекцию столбцов этого индекса
AddColumn idx, cCol1
AddColumn idx, cCol2

' cCol1 - это столбец который мы хотим добавить в наш индекс
' для индексирования. Писать можно по разному, например:
' Dim cCol1 as Column
' Set cCol1 = cat.Tables("МояТаблица").Columns("Столбец1")

' Добавим индекс в коллекцию Indexes объекта Table
Set idxs = tbl.Indexes
idxs.Append idx


вот вроде и все, чтобы создать Primary key сразу по нескольким столбцам

P.S. да, забыл написать, что tbl - это конечно имеется ввиду Set tbl = cat.Tables("МояТаблица"), ну а cat ты догадываешься конечно же что такое
3.0K
11 февраля 2005 года
crujer
20 / / 29.01.2004
Цитата:
Originally posted by SergeySV


Так, ну значит:
Код:
' Создаем новый объект индекса
Set idx = New ADOX.Index
idx.Name = "мойпервичныйключ"

' Сделаем новый индекс первичным ключом
idx.PrimaryKey = True
idx.Unique = True

' Теперь создадим индексированные столбцы
' и добавим их в коллекцию столбцов этого индекса
AddColumn idx, cCol1
AddColumn idx, cCol2

' cCol1 - это столбец который мы хотим добавить в наш индекс
' для индексирования. Писать можно по разному, например:
' Dim cCol1 as Column
' Set cCol1 = cat.Tables("МояТаблица").Columns("Столбец1")

' Добавим индекс в коллекцию Indexes объекта Table
Set idxs = tbl.Indexes
idxs.Append idx


вот вроде и все, чтобы создать Primary key сразу по нескольким столбцам

P.S. да, забыл написать, что tbl - это конечно имеется ввиду Set tbl = cat.Tables("МояТаблица"), ну а cat ты догадываешься конечно же что такое



Ммм... Спасибо, но вот я не могу найти функции AddColumn в ВБ. MSDN выдаёт такую фунцию только в FoxPro. Ты функцией не ошибся?

258
11 февраля 2005 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by crujer


Ммм... Спасибо, но вот я не могу найти функции AddColumn в ВБ. MSDN выдаёт такую фунцию только в FoxPro. Ты функцией не ошибся?



Извиняюсь, это самопальная функция по Гетцу, по смыслу, если убрать лишние проверки она делает следующее, получив имя столбца и ссылку на создаваемый первичный индекс - idx:

 
Код:
Set col = New ADOX.Column
col.Name = "имя твоего реального столбца"
idx.Columns.Append col

Set col = Nothing


Т.е. для первичного ключа необходимо создать новые столбцы-пустышки с именами столбцов по которым будет задаваться первичный ключ и добавить их в коллекцию idx.Columns этого ключа через метод .Append
3.0K
04 марта 2005 года
crujer
20 / / 29.01.2004
Цитата:
Originally posted by SergeySV


Извиняюсь, это самопальная функция по Гетцу, по смыслу, если убрать лишние проверки она делает следующее, получив имя столбца и ссылку на создаваемый первичный индекс - idx:
 
Код:
Set col = New ADOX.Column
col.Name = "имя твоего реального столбца"
idx.Columns.Append col

Set col = Nothing


Т.е. для первичного ключа необходимо создать новые столбцы-пустышки с именами столбцов по которым будет задаваться первичный ключ и добавить их в коллекцию idx.Columns этого ключа через метод .Append



Проверил. Действительно, работает. Спасибо большое.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог