Я пытаюсь сделать SQL-запрос, который выполняет следующие действия:
- Выбрать все таблицы в схеме
- Выделить все столбцы из таблицы
- Выберите тип столбца (char, int, tinyint и т. д.)
- Выберите тип индекса столбцов или NULL (тип индекса FK или PK).
- Если есть индекс внешнего ключа, выберите основную таблицу
Затем эти данные должны быть помещены в файл XML. Обратите внимание, что это в SQL Anywhere
.
Код для файла XML легко написать, но я застрял на запросе.
В настоящее время у меня есть запрос, который может выбрать все столбцы, их таблицу и их тип данных.
SELECT t.table_name AS table_name,
c.column_name AS column_name,
c.base_type_str
FROM sys.systabcol c
INNER JOIN sys.systab t
ON t.table_id = c.table_id
WHERE t.table_type_str = 'BASE'
AND t.table_name NOT LIKE 'ISYS%';
который в настоящее время возвращает, например:
[6585]=>
array(3) {
["table_name"]=>
string(17) "my_table"
["column_name"]=>
string(6) "number"
["base_type_str"]=>
string(7) "integer"
}
Мой желаемый результат будет (например):
[6585]=>
array(3) {
["table_name"]=>
string(17) "my_table"
["column_name"]=>
string(6) "number"
["base_type_str"]=>
string(7) "integer" // or other types
["index_type"]=>
string(7) "FK" // or "PK" or "NULL"
["primary_table"]=>
string(7) "some_other_table" // or "NULL"
}
Я знаю, что в SQL Anywhere есть такие системные таблицы, как: SYSFKEY
, SYSIDX
и SYSIDXCOL
, но я понятия не имею, как реализовать это в своем собственном запросе.
Я поискал в Интернете и могу найти множество примеров для других служб SQL, но ни одного для SQL Anywhere.
Мне действительно не помешала бы помощь в этом.
Обновление 1:
Итак, я выяснил, что в таблице SYSFKEY
есть несколько интересных столбцов.
- ид_иностранной_таблицы
- иностранный_индекс_ид
- идентификатор основной_таблицы
где, кажется, что primary_table_id относится к внешней таблице.
Также в таблице SYSIDX
есть столбцы
- table_id
- index_id
Надеюсь, я смогу как-то связать все это воедино
Обновление 2: Итак, я написал новый запрос, который на самом деле работает на удивление хорошо. Я думал, что исправил это, пока не столкнулся с некоторыми странностями.
На данный момент запрос такой:
SELECT tab.table_name as table_name,
col.column_name as column_name,
col.`default` as default_value,
col.base_type_str,
(
case idx.index_category
when 1 then 'PK'
when 2 then 'FK'
else 'NULL'
end
) as index_type,
tab1.table_name as foreign_table
FROM sys.systabcol col
INNER JOIN sys.systab tab
ON tab.table_id = col.table_id
LEFT JOIN sys.sysidx idx
ON idx.table_id = col.table_id
LEFT JOIN sys.sysidxcol idxc
ON idxc.table_id = idx.table_id AND idxc.index_id = idx.index_id
LEFT JOIN sys.sysfkey fk
ON fk.foreign_table_id = idx.table_id AND fk.foreign_index_id = idx.index_id
LEFT JOIN sys.systab tab1
ON tab1.table_id = fk.primary_table_id
WHERE tab.table_name LIKE 'tab%' OR tab.table_name LIKE 'vw%';
И это на самом деле возвращает много полезной информации! Но происходит что-то странное.
В таблице есть несколько первичных ключей. Возможно, создатели так задумали, что каждое поле вместе является первичным ключом, но мне это кажется странным.
Также есть несколько дубликатов (несколько строк со столбцами, которые были там раньше)
Example with multiple PK:
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
<table>
<thead>
<tr>
<th colspan="4">tabMobilinkTabellen</th>
</tr>
</thead>
<tbody>
<tr><th>Key</th><th>Column</th><th>Type</th><th>Default</th></tr><tr><td>PK</td><td>MltGid</td><td>integer</td><td>autoincrement</td></tr><tr><td>PK</td><td>MltLastModified</td><td>timestamp</td><td>timestamp</td></tr><tr><td>PK</td><td>MltTablename</td><td>nchar(128)</td><td>''</td></tr> </tbody>
</table>
Пример с несколькими индексами:
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
<table>
<thead>
<tr>
<th colspan="4">tabAanhef</th>
</tr>
</thead>
<tbody>
<tr><th>Key</th><th>Column</th><th>Type</th><th>Default</th></tr><tr><td><a href="?table=tabTaal">FK</a></td><td>AanhefGid</td><td>integer</td><td>autoincrement</td></tr><tr><td></td><td>AanhefGid</td><td>integer</td><td>autoincrement</td></tr><tr><td></td><td>AanhefGid</td><td>integer</td><td>autoincrement</td></tr><tr><td>PK</td><td>AanhefGid</td><td>integer</td><td>autoincrement</td></tr><tr><td><a href="?table=tabTaal">FK</a></td><td>AanhefTaalGid</td><td>integer</td><td></td></tr><tr><td></td><td>AanhefTaalGid</td><td>integer</td><td></td></tr><tr><td></td><td>AanhefTaalGid</td><td>integer</td><td></td></tr><tr><td>PK</td><td>AanhefTaalGid</td><td>integer</td><td></td></tr><tr><td><a href="?table=tabTaal">FK</a></td><td>GeslachtAanhef</td><td>smallint</td><td>0</td></tr><tr><td></td><td>GeslachtAanhef</td><td>smallint</td><td>0</td></tr><tr><td></td><td>GeslachtAanhef</td><td>smallint</td><td>0</td></tr><tr><td>PK</td><td>GeslachtAanhef</td><td>smallint</td><td>0</td></tr><tr><td><a href="?table=tabTaal">FK</a></td><td>TekstAanhef</td><td>nchar(40)</td><td>''</td></tr><tr><td></td><td>TekstAanhef</td><td>nchar(40)</td><td>''</td></tr><tr><td></td><td>TekstAanhef</td><td>nchar(40)</td><td>''</td></tr><tr><td>PK</td><td>TekstAanhef</td><td>nchar(40)</td><td>''</td></tr><tr><td><a href="?table=tabTaal">FK</a></td><td>TekstAdres</td><td>nchar(40)</td><td>''</td></tr><tr><td></td><td>TekstAdres</td><td>nchar(40)</td><td>''</td></tr><tr><td></td><td>TekstAdres</td><td>nchar(40)</td><td>''</td></tr><tr><td>PK</td><td>TekstAdres</td><td>nchar(40)</td><td>''</td></tr><tr><td><a href="?table=tabTaal">FK</a></td><td>TekstBrief</td><td>nchar(40)</td><td>''</td></tr><tr><td></td><td>TekstBrief</td><td>nchar(40)</td><td>''</td></tr><tr><td></td><td>TekstBrief</td><td>nchar(40)</td><td>''</td></tr><tr><td>PK</td><td>TekstBrief</td><td>nchar(40)</td><td>''</td></tr> </tbody>
</table>
Возможно, мне следует объединить их вместе, но все же странно, что в одном столбце несколько индексов FK, верно? Или, возможно, запрос застревает и продолжает выдавать одну и ту же информацию в каждом результате?