簡體   English   中英

SQL Anywhere 查詢以挖掘架構結構

[英]SQL Anywhere query to dig schema structure

我正在嘗試進行 SQL 查詢,該查詢執行以下操作:

  1. Select 模式中的所有表
  2. Select 表中的所有列
  3. Select 列類型(char、int、tinyint 等)
  4. Select 列索引類型或 NULL(索引類型為 FK 或 PK)
  5. 如果有外鍵索引,主表select

然后應將此數據放入 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 有系統表,例如: SYSFKEYSYSIDXSYSIDXCOL ,但我不知道如何在我自己的查詢中實現它。

我在互聯網上環顧四周,我可以找到很多其他 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, 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;

此查詢將:

  • Select 列的表名為table_name
  • Select 當前列名為column_name
  • Select 列的默認值為default_value
  • Select 列數據類型為base_type_str (想想 int、bool、date 等)
  • 以 index_category 列為例,其中 1 表示該列是 PK,2 表示 FK,其他任何內容都將返回為 '' as index_type
  • FK 引用的表名作為foreign_table

where 子句確實特定於我的數據庫模式,因為它過濾到所有tab% (表)和vw% (視圖),但這可以是任何東西。 雖然不指定時也會為您提供所有系統表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM