SQL Anywhere 查询挖掘模式结构
SQL Anywhere query to dig schema structure
我正在尝试创建一个 SQL 查询来执行以下操作:
- Select 架构中的所有 tables
- Select 来自 table
的所有列
- Select 列类型(char、int、tinyint 等)
- Select 列索引类型或 NULL(索引类型为 FK 或 PK)
- 如果有外键索引,select主table
此数据应放入 XML 文件中。请注意,这是在 SQL Anywhere
.
XML 文件的代码很容易写,但我卡在查询中。
我目前有一个查询可以 select 所有列,它们的 table 和它们的数据类型。
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%';
当前 returns 例如:
[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 有系统 table,例如:SYSFKEY
、SYSIDX
和 SYSIDXCOL
,但我不知道我是怎么做到的将其实现到我自己的查询中。
我在互联网上四处寻找,可以找到很多其他 SQL 服务的示例,但是 none
对于 SQL 任何地方。
我真的需要一些帮助。
更新 1:
所以我发现 table SYSFKEY
有一些有趣的专栏。
- foreign_table_id
- foreign_index_id
- primary_table_id
这里的primary_table_id好像是指国外的table.
table SYSIDX
也有列
- table_id
- index_id
我希望我能以某种方式将所有这些联系在一起
更新二:
所以我写了一个新的查询,实际上效果出奇的好。我以为我修复了它,直到我 运行 遇到一些奇怪的事情。
当前查询是这样的:
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%';
而这实际上 returns 很多有用的信息!但是奇怪的事情发生了。
一个table中有多个主键。也许这就是创作者设计的方式,每个字段在一起就是主键,但对我来说似乎很奇怪。
也有多个重复项(多行和以前存在的列)
具有多个 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 索引,对吧?或者可能查询卡住了,只是在每个结果中不断转储相同的信息?
所以我花了很多时间,但我终于想出了一个办法。我正在分享这个答案,以防其他人遇到这个问题。
答案并不完美,即使使用 LIST()
函数,仍会产生一些重复的行。这只有在存在中间 table 时才会成为问题。我仍在尝试解决这个问题,但大多数问题都可以通过简单的 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`, col.base_type_str, tab1.table_name ORDER BY index_type DESC;
此查询将:
- Select 列的 table 名称为
table_name
- Select 当前列名称为
column_name
- Select列的默认值为
default_value
- Select 列数据类型为
base_type_str
(考虑 int、bool、date 等)
- 大小写 index_category 列,其中 1 表示该列是 PK,2 表示 FK,其他任何内容都将 return as '' as
index_type
- FK 引用的 table 名称为
foreign_table
where 子句确实特定于我的数据库模式,因为它过滤所有 tab%
(tables)和 vw%
(视图),但这可以是任何东西。尽管在不指定时也会为您提供所有系统 tables。
我正在尝试创建一个 SQL 查询来执行以下操作:
- Select 架构中的所有 tables
- Select 来自 table 的所有列
- Select 列类型(char、int、tinyint 等)
- Select 列索引类型或 NULL(索引类型为 FK 或 PK)
- 如果有外键索引,select主table
此数据应放入 XML 文件中。请注意,这是在 SQL Anywhere
.
XML 文件的代码很容易写,但我卡在查询中。
我目前有一个查询可以 select 所有列,它们的 table 和它们的数据类型。
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%';
当前 returns 例如:
[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 有系统 table,例如:SYSFKEY
、SYSIDX
和 SYSIDXCOL
,但我不知道我是怎么做到的将其实现到我自己的查询中。
我在互联网上四处寻找,可以找到很多其他 SQL 服务的示例,但是 none 对于 SQL 任何地方。
我真的需要一些帮助。
更新 1:
所以我发现 table SYSFKEY
有一些有趣的专栏。
- foreign_table_id
- foreign_index_id
- primary_table_id
这里的primary_table_id好像是指国外的table.
table SYSIDX
也有列
- table_id
- index_id
我希望我能以某种方式将所有这些联系在一起
更新二: 所以我写了一个新的查询,实际上效果出奇的好。我以为我修复了它,直到我 运行 遇到一些奇怪的事情。
当前查询是这样的:
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%';
而这实际上 returns 很多有用的信息!但是奇怪的事情发生了。
一个table中有多个主键。也许这就是创作者设计的方式,每个字段在一起就是主键,但对我来说似乎很奇怪。
也有多个重复项(多行和以前存在的列)
具有多个 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 索引,对吧?或者可能查询卡住了,只是在每个结果中不断转储相同的信息?
所以我花了很多时间,但我终于想出了一个办法。我正在分享这个答案,以防其他人遇到这个问题。
答案并不完美,即使使用 LIST()
函数,仍会产生一些重复的行。这只有在存在中间 table 时才会成为问题。我仍在尝试解决这个问题,但大多数问题都可以通过简单的 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`, col.base_type_str, tab1.table_name ORDER BY index_type DESC;
此查询将:
- Select 列的 table 名称为
table_name
- Select 当前列名称为
column_name
- Select列的默认值为
default_value
- Select 列数据类型为
base_type_str
(考虑 int、bool、date 等) - 大小写 index_category 列,其中 1 表示该列是 PK,2 表示 FK,其他任何内容都将 return as '' as
index_type
- FK 引用的 table 名称为
foreign_table
where 子句确实特定于我的数据库模式,因为它过滤所有 tab%
(tables)和 vw%
(视图),但这可以是任何东西。尽管在不指定时也会为您提供所有系统 tables。