【问题标题】:How do I get constraint details from the name in Informix?如何从 Informix 中的名称获取约束详细信息?
【发布时间】:2010-09-24 02:50:37
【问题描述】:

在编写大型事务(大量插入、删除、更新)并因此违反 Informix(v10,但也应适用于其他版本)中的约束时,我收到一条不太有用的消息,例如,我违反了约束r190_710。我怎样才能知道哪些表和键被某个约束所覆盖,我只知道它的名称?

【问题讨论】:

    标签: database constraints informix


    【解决方案1】:

    Tony Andrews 建议(指向 URL 的不同端点):

    Informix Guide to SQL: Reference看来,您应该查看系统目录表 SYSCONSTRAINTS 和 SYSINDICES。

    该手册中描述了 Informix 系统目录。

    毫无疑问,SysConstraints 表是分析约束的起点;您可以在该表中找到约束名称,然后您可以从那里找到其他详细信息。

    但是,您还必须查看其他表,而不仅仅是(甚至直接)SysIndices。

    例如,我的数据库中的表有很多 NOT NULL 约束。对于这些,约束类型为“N”,无需在其他地方查找更多信息。

    约束类型'P'表示主键;这需要通过 SysIndexes 视图或 SysIndices 表进行更多分析。同样,约束类型“U”表示唯一约束,需要来自 SysIndexes 视图或 SysIndices 表的额外信息。

    约束类型“C”表示检查约束;约束的文本(和二进制编译形式)可在 SysChecks 表中找到(数据类型为“T”和“B”;数据或多或少使用 Base-64 编码,但没有“=”填充最后并为 62 和 63 使用不同的字符)。

    最后,约束类型“R”表示参照完整性约束。您可以使用 SysReferences 表来找出引用了哪个表,并使用 SysIndexes 或 SysIndices 来确定使用了引用和被引用表上的哪些索引,并从中可以发现相关的列。这可能会很麻烦!

    【讨论】:

      【解决方案2】:

      表中具有约束的列

      SELECT
          a.tabname, b.constrname, d.colname
      FROM
          systables a, sysconstraints b, sysindexes c, syscolumns d
      WHERE
          a.tabname = 'your_table_name_here'
      AND
          b.tabid = a.tabid
      AND
          c.idxname = b.idxname
      AND
          d.tabid = a.tabid
      AND
      (
          d.colno = c.part1 or 
          d.colno = c.part2 or 
          d.colno = c.part3 or 
          d.colno = c.part4 or 
          d.colno = c.part5 or 
          d.colno = c.part6 or 
          d.colno = c.part7 or 
          d.colno = c.part8 or 
          d.colno = c.part9 or 
          d.colno = c.part10 or 
          d.colno = c.part11 or 
          d.colno = c.part12 or
          d.colno = c.part13 or 
          d.colno = c.part14 or 
          d.colno = c.part15 or 
          d.colno = c.part16
      )
      ORDER BY
          a.tabname, 
          b.constrname,
          d.colname
      

      【讨论】:

      • 请注意,这不会给您 CHECK 约束,因为 sysconstraints.idxname 对于 CHECK 约束始终为空
      【解决方案3】:

      我一直在使用以下查询来获取有关不同类型约束的更多信息。 它基于对系统表的一些探索和对系统目录的一些解释。

      sysconstraints.constrtype 表示约束的类型:

      • P = 主键
      • U = 唯一键/备用键
      • N = 非空
      • C = 检查
      • R = 参考/外键
      select
        tab.tabname,
        constr.*, 
        chk.*,
        c1.colname col1,
        c2.colname col2,
        c3.colname col3,
        c4.colname col4,
        c5.colname col5
      from sysconstraints constr
        join systables tab on tab.tabid = constr.tabid
        left outer join syschecks chk on chk.constrid = constr.constrid and chk.type = 'T'
        left outer join sysindexes i on i.idxname = constr.idxname
        left outer join syscolumns c1 on c1.tabid = tab.tabid and c1.colno = abs(i.part1)
        left outer join syscolumns c2 on c2.tabid = tab.tabid and c2.colno = abs(i.part2)
        left outer join syscolumns c3 on c3.tabid = tab.tabid and c3.colno = abs(i.part3)
        left outer join syscolumns c4 on c4.tabid = tab.tabid and c4.colno = abs(i.part4)
        left outer join syscolumns c5 on c5.tabid = tab.tabid and c5.colno = abs(i.part5)
      where constr.constrname = 'your constraint name'
      

      【讨论】:

        【解决方案4】:

        获取受约束“r190_710”影响的表:

        select TABNAME from SYSTABLES where TABID IN
        (select TABID from sysconstraints where CONSTRID IN
        (select CONSTRID from sysreferences where PTABID IN 
        (select TABID from sysconstraints where CONSTRNAME= "r190_710" )
        )
        );
        

        【讨论】:

          【解决方案5】:

          Informix Guide to SQL: Reference看来,您应该查看系统目录表 SYSCONSTRAINTS 和 SYSINDICES。

          【讨论】:

            【解决方案6】:

            从 www.iiug.org(国际 Informix 用户组)的网上冲浪中,我发现了这个不太容易的解决方案。

            (1) 从约束名称中获取引用约束数据(您可以通过将“AND sc.constrname = ?”替换为“AND st.tabname MATCHES ?”来获取表的所有约束)。该语句在这里选择了一些不必要的字段,因为它们在其他情况下可能会很有趣。

            SELECT si.part1, si.part2, si.part3, si.part4, si.part5, 
                si.part6, si.part7, si.part8, si.part9, si.part10, 
                si.part11, si.part12, si.part13, si.part14, si.part15, si.part16, 
                st.tabname, rt.tabname as reftable, sr.primary as primconstr, 
                sr.delrule, sc.constrid, sc.constrname, sc.constrtype, 
                si.idxname, si.tabid as tabid, rc.tabid as rtabid 
            FROM 'informix'.systables st, 'informix'.sysconstraints sc, 
                 'informix'.sysindexes si, 'informix'.sysreferences sr, 
                 'informix'.systables rt, 'informix'.sysconstraints rc 
            WHERE st.tabid = sc.tabid 
              AND st.tabtype != 'Q' 
              AND st.tabname NOT MATCHES 'cdr_deltab_[0-9][0-9][0-9][0-9][0-9][0-9]*' 
              AND rt.tabid = sr.ptabid 
              AND rc.tabid = sr.ptabid
              AND sc.constrid = sr.constrid 
              AND sc.tabid = si.tabid 
              AND sc.idxname = si.idxname 
              AND sc.constrtype = 'R' 
              AND sc.constrname = ?
              AND sr.primary = rc.constrid 
            ORDER BY si.tabid, sc.constrname
            

            (2) 使用part1-part16 来确定哪一列受约束影响:part[n] 包含一个不同于0 的值,其中包含所用列的列号。使用 (3) 查找列的名称。

            如果 constrtype 为 'R'(引用),则使用以下语句查找引用表的部分:

            SELECT part1, part2, part3, part4, part5, part6, part7, part8, 
                part9, part10, part11, part12, part13, part14, part15, part16 
            FROM 'informix'.sysindexes si, 'informix'.sysconstraints sc 
            WHERE si.tabid = sc.tabid 
            AND si.idxname = sc.idxname 
            AND sc.constrid = ? -- primconstr from (1)
            

            (3) 现在可以使用 (1) 中的 tabid 和 rtabid(用于引用约束)来获取表的列:

            SELECT colno, colname 
            FROM 'informix'.syscolumns 
            WHERE tabid = ? -- tabid(for referenced) or rtabid(for referencing) from (1)
              AND colno = ? -- via parts from (1) and (2)
            ORDER BY colno
            

            (4) 如果constrtype为'C',则获取校验信息如下:

            SELECT type, seqno, checktext
            FROM 'informix'.syschecks
            WHERE constrid = ? -- constrid from (1)
            

            确实很毛茸茸

            【讨论】:

              【解决方案7】:

              如果你的约束被命名为constraint_c6,这里是如何转储它的定义(好吧,你仍然需要连接行,因为它们将被空格分隔):

              OUTPUT TO '/tmp/constraint_c6.sql' WITHOUT HEADINGS
              SELECT ch.checktext
              FROM  syschecks ch, sysconstraints co
              WHERE ch.constrid = co.constrid
                AND ch.type = 'T' -- text lines only
                AND co.constrname = 'constraint_c6' 
              ORDER BY ch.seqno;
              

              【讨论】:

                猜你喜欢
                • 2019-12-30
                • 2016-03-26
                • 1970-01-01
                • 1970-01-01
                • 2022-08-19
                • 2018-04-25
                • 1970-01-01
                • 2014-10-15
                • 2023-03-08
                相关资源
                最近更新 更多