如何根据列值从 table 中知道列名

How to know the column name from a table based on the column values

我在 Informix 工作,我想知道是否有一种简单的方法可以通过其可能的列值了解 tabname/colname。

例如:

table1

Register 1
==========
id        1
col1      3
col2      Y

Register 2
==========
id       2
col1     43
col2     X 

Register 3
==========
id       2
col1     0
col2     Z 

Register 4
==========
id       2
col1     23
col2     F 


table2

Register 1
==========
id        1
col1      X
col2      Y

Register 2
==========
id       2
col1     X
col2     X 

Register 3
==========
id       2
col1     Z
col2     Z 

Register 4
==========
id       2
col1     X
col2     X 


table3

Register 1
==========
id       1
col1   ASX

有了这个数据库,如果我想知道包含 X、Y 和 Z(以及其他值)的数据库的列名称及其相关的标签名称。

可能是这样的:

select tabname, colname 
where ('X','Y','Z') in colnamevalues --this has been invented by me

这应该 return 以下值:

table1.col2 
table2.col1
table2.col2

--Note that the columns fetched contains also other values 
--different from 'X', 'Y' and 'Z' but T didn't fix in this case 
--the whole list of values, only some of them

其他的Q&A我也查询过,但是都是想用其他数据库的一些功能,比如Oracle或者SQLServer,我不是很懂。

您可以通过查询 systables:

获取数据库中存在的所有 table
SELECT  tabname
FROM    systables
WHERE   tabtype = 'T'   --get only tables
        AND tabid > 99; --skip catalog tables

您可以将其加入 syscolumns table 以获取列:

SELECT  t.tabname, c.colname
FROM    systables t
    INNER JOIN syscolumns c ON (c.tabid = t.tabid)
WHERE   t.tabtype = 'T' AND t.tabid > 99;

如果您知道值的类型,您甚至可以过滤它。例如,如果您正在寻找 "strings":

SELECT  t.tabname, c.colname
FROM    systables t
    INNER JOIN syscolumns c ON (c.tabid = t.tabid)
WHERE   t.tabtype = 'T' AND t.tabid > 99
        AND MOD(c.coltype,256) IN (
            0,  --CHAR
            13, --VARCHAR
            15, --NCHAR
            16, --NVARCHAR
            40, --LVARCHAR
            43  --LVARCHAR
        );

下一个示例可行,但它确实应该经过优化和防弹,但可以让您开始。

当我有空的时候,我会再看一遍,检查哪些可以优化,并进行一些错误处理。

另一种方法是编写脚本,OS 你是什么运行?

架构创建:

CREATE TABLE tab1(
    id      INT,
    col1    CHAR(3),
    col2    CHAR(3)
);

INSERT INTO tab1 VALUES (1, 3, 'Y');
INSERT INTO tab1 VALUES (2, 43, 'X');
INSERT INTO tab1 VALUES (2, 0, 'Z');
INSERT INTO tab1 VALUES (2, 23, 'F');

CREATE TABLE tab2(
    id      INT,
    col1    CHAR(3),
    col2    CHAR(3)
);

INSERT INTO tab2 VALUES (1, 'X', 'Y');
INSERT INTO tab2 VALUES (2, 'X', 'X');
INSERT INTO tab2 VALUES (2, 'Z', 'Z');
INSERT INTO tab2 VALUES (2, 'X', 'X');

CREATE TABLE tab3(
    id      INT,
    col1    CHAR(3)
);

INSERT INTO tab3 VALUES (1, 'ASX');

示例函数:

CREATE FUNCTION get_columns()
    RETURNING LVARCHAR(257) AS col;

    DEFINE stmt     VARCHAR(255);
    DEFINE tab_name VARCHAR(128,0);
    DEFINE tab_id   INTEGER;
    DEFINE col_name VARCHAR(128,0);

    DEFINE o_tname VARCHAR(128,0);
    DEFINE o_cname VARCHAR(128,0);

    CREATE TEMP TABLE out_table(
        t_name VARCHAR(128,0),
        c_name VARCHAR(128,0)
    );

    CREATE TEMP TABLE tab_v (
        col1 VARCHAR(255)
    );

    INSERT INTO tab_v VALUES ('X');
    INSERT INTO tab_v VALUES ('Y');
    INSERT INTO tab_v VALUES ('Z');

    FOREACH tables FOR 
        SELECT  tabname, tabid
        INTO    tab_name, tab_id 
        FROM    systables 
        WHERE   tabid > 99 AND tabtype = 'T'

            FOREACH column FOR
                SELECT  colname
                INTO    col_name
                FROM    syscolumns
                WHERE   tabid = tab_id
                        AND MOD(coltype,256) IN (
                            0,  --CHAR
                            13, --VARCHAR
                            15, --NCHAR
                            16, --NVARCHAR
                            40, --LVARCHAR
                            43  --LVARCHAR
                )

                    LET stmt = "INSERT INTO out_table "||
                                "SELECT '"||tab_name||"', '"||col_name||"' "||
                                "FROM "||tab_name||" "||
                                "WHERE EXISTS (SELECT 1 FROM tab_v v WHERE v.col1 = "||col_name||");";

                    EXECUTE IMMEDIATE stmt;
            END FOREACH
    END FOREACH

    FOREACH out FOR
        SELECT  UNIQUE t_name, c_name
        INTO    o_tname, o_cname
        FROM    out_table
            RETURN o_tname||"."||o_cname WITH RESUME;
    END FOREACH

    DROP TABLE out_table;
    DROP TABLE tab_v;
END FUNCTION;

EXECUTE FUNCTION get_columns();