[英]SQL Anywhere query to dig schema structure
我正在嘗試進行 SQL 查詢,該查詢執行以下操作:
然后應將此數據放入 XML 文件中。 請注意,這是在SQL Anywhere
中。
XML 文件的代碼很容易編寫,但我被困在查詢中。
我目前有一個查詢可以 select 所有列、它們的表和它們的數據類型。
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
也有列
我希望我能以某種方式將所有這些聯系在一起
更新 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, 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()
function,仍然會產生一些重復的行。 這只有在有中間表時才會成為問題。 我仍在嘗試解決這個問題,但大多數問題都可以通過簡單的 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;
此查詢將:
table_name
column_name
default_value
base_type_str
(想想 int、bool、date 等)index_type
foreign_table
where 子句確實特定於我的數據庫模式,因為它過濾到所有tab%
(表)和vw%
(視圖),但這可以是任何東西。 雖然不指定時也會為您提供所有系統表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.