如何解决SQL Anywhere 查询以挖掘架构结构
- 选择架构中的所有表
- 选择表格中的所有列
- 选择列类型(char、int、tinyint 等)
- 选择列索引类型或NULL(索引类型为FK或PK)
- 如果有外键索引,选择主表
然后应将此数据放入 XML 文件中。请注意,这是在 sql Anywhere
中。
我目前有一个可以选择所有列、它们的表和它们的数据类型的查询。
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
有一些有趣的列。
- foreign_table_id
- foreign_index_id
- primary_table_id
其中 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%';
这实际上返回了很多有用的信息!但奇怪的事情正在发生。
一个表中有多个主键。也许这就是创作者设计的方式,每个字段一起是主键,但对我来说似乎很奇怪。
还有多个重复项(多行,其中的列之前已经存在)
具有多个 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,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 索引仍然很奇怪,对吧?或者查询卡住了,只是在每个结果中不断转储相同的信息?
解决方法
所以这花了我很多时间,但我终于找到了一种方法。我正在分享这个答案,以防其他人遇到这个问题。
答案并不完美,即使使用 LIST()
函数,仍然会产生一些重复的行。这仅在存在中间表时才会成为问题。我仍在尝试解决这个问题,但大多数问题都可以通过简单的 PHP(或您的首选语言)过滤掉。
我现在的最终查询是:
SELECT tab.table_name as table_name,col.column_name as column_name,col.`default` as default_value,col.base_type_str,LIST(
case idx.index_category
when 1 then 'PK'
when 2 then 'FK'
end
) as index_type,tab1.table_name as foreign_table
FROM sys.systabcol col
LEFT JOIN sys.sysidxcol idxc
ON idxc.table_id = col.table_id AND idxc.column_id = col.column_id
INNER JOIN sys.systab tab
ON col.table_id = tab.table_id
LEFT JOIN sys.sysidx idx
ON idx.table_id = idxc.table_id AND idx.index_id = idxc.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%' GROUP BY tab.table_name,col.column_name,col.`default`,tab1.table_name ORDER BY index_type DESC;
此查询将:
- 选择列的表名为
table_name
- 选择当前列名称为
column_name
- 选择列的默认值为
default_value
- 选择列数据类型为
base_type_str
(想想 int、bool、date 等) - 以 index_category 列为例,其中 1 表示该列是 PK,2 表示该列是 FK,其他任何内容都将返回为 '' as
index_type
- FK 引用的表名称为
foreign_table
where 子句确实特定于我的数据库架构,因为它过滤到所有 tab%
(表)和 vw%
(视图),但这可以是任何东西。虽然不指定时也会为您提供所有系统表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。