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 символов. Как проблему решить? Заранее благодарен.
Проверьте содержимое массива NamesArr - возможно в результате другой ошибки в нем есть повторяющиеся имена?
Попробуйте для имен индексов дать префикс какой-нибудь (типа ndx), возможно есть особенности именования объектов в БД, которую Вы используете.
Я проверил Ваш код для MS Access 2000 - замечательно работает.
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
На самом деле, приведённый код был упрощённым. Названия базы, таблиц и полей, а так же свойства полей беруться из х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 - счётчик, соответствующий порядку обрабатываемой таблицы. Здесь цикл с обработкой таблицы не показан, цикл обработки поля вложен в цикл обработки таблицы.
Заренее благодарен.
Так как же у тебя будет два первичных ключа? на то он и первичный, чтобы одному быть... может тебе нужен первичный ключ составной? чтобы из нескольких индексов состоял
Ну да, составной собственно и имелся ввиду.
Ну да, составной собственно и имелся ввиду.
Так, ну значит:
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 ты догадываешься конечно же что такое
Так, ну значит:
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. Ты функцией не ошибся?
Ммм... Спасибо, но вот я не могу найти функции AddColumn в ВБ. MSDN выдаёт такую фунцию только в FoxPro. Ты функцией не ошибся?
Извиняюсь, это самопальная функция по Гетцу, по смыслу, если убрать лишние проверки она делает следующее, получив имя столбца и ссылку на создаваемый первичный индекс - idx:
col.Name = "имя твоего реального столбца"
idx.Columns.Append col
Set col = Nothing
Т.е. для первичного ключа необходимо создать новые столбцы-пустышки с именами столбцов по которым будет задаваться первичный ключ и добавить их в коллекцию idx.Columns этого ключа через метод .Append
Извиняюсь, это самопальная функция по Гетцу, по смыслу, если убрать лишние проверки она делает следующее, получив имя столбца и ссылку на создаваемый первичный индекс - idx:
col.Name = "имя твоего реального столбца"
idx.Columns.Append col
Set col = Nothing
Т.е. для первичного ключа необходимо создать новые столбцы-пустышки с именами столбцов по которым будет задаваться первичный ключ и добавить их в коллекцию idx.Columns этого ключа через метод .Append
Проверил. Действительно, работает. Спасибо большое.