如何根据列值了解表中的列名

时间:2016-04-22 11:55:08

标签: sql informix

我在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的数据库的colnames及其相关的tabnames(其他值是其他值)。

可能是这样的:

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

这应返回以下值:

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或SQL Server,我不太了解它们。

1 个答案:

答案 0 :(得分:1)

您可以通过查询systables

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

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

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;

如果您知道值的类型,您甚至可以过滤它。例如,如果您正在寻找“字符串”:

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
        );

下一个例子有效,但它确实应该进行优化和防弹,但可以让你开始。

当我有时间时,我再看看它并检查可以优化的内容并进行一些错误处理。

另一种方法是编写脚本,你运行的是什么操作系统

架构创建:

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();