I'm trying to make a SQL query which does the following things:
- Select all tables in a schema
- Select all columns from the table
- Select the columns type (char, int, tinyint, etc)
- Select the columns index type or NULL (index type being FK or PK)
- If there is a foreign key index, select the primary table
This data should then be put in a XML file. Please note that this is in SQL Anywhere
.
The code for the XML file is easily written, but I'm stuck at the query.
I currently have a query that can select all columns, their table and their data type.
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%';
which currently returns for example:
[6585]=>
array(3) {
["table_name"]=>
string(17) "my_table"
["column_name"]=>
string(6) "number"
["base_type_str"]=>
string(7) "integer"
}
My desired result would be (for example):
[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"
}
I'm aware SQL Anywhere has system tables like: SYSFKEY
, SYSIDX
and SYSIDXCOL
, but I have no idea how I'd implement this into my own query.
I've looked around on the internet, and I can find a lot of examples for other SQL services, but none for SQL Anywhere.
I could really use some assistance on this.
Update 1:
So I've figured out that the table SYSFKEY
has some interesting columns.
- foreign_table_id
- foreign_index_id
- primary_table_id
where primary_table_id seems to refer to the foreign table.
Also the table SYSIDX
has the columns
- table_id
- index_id
I hope I can somehow connect all of this together
Update 2: So I've written a new query, which does suprisingly good actually. I thought I fixed it, until I ran into some oddities.
The query is currently this:
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%';
And this actually returns a lot of useful information! But something weird is happening.
There are multiple primary keys in a table. Perhaps thats just how the creators designed it to be, that every field together is the primary key, but it seems odd to me.
There are also multiple duplicates (multiple rows with columns that have been there before)
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>
Example with multiple indexes:
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>
Perhaps I should merge them together, but then still its odd there are multiple FK indexes on one column, right? Or perhaps the query gets stuck and just keeps dumping the same information in every result?