AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 224556
Accepted
Tsukasa
Tsukasa
Asked: 2018-12-11 06:00:34 +0800 CST2018-12-11 06:00:34 +0800 CST 2018-12-11 06:00:34 +0800 CST

插入约束问题

  • 772

使用 IBM Informix 数据库。如果我手动指定 order_no,该语句有效,但如果我尝试在查询中递增它,它就会失败。

表结构

patkey serial
notetype char(4)
order_no int

约束是 patkey、notetype 和 order_no

我可以手动插入运行以下命令并增加 order_no

insert into patnotes (patkey, notetype, order_no) values (5000, 'GEN', 3)

我想在插入语句中增加它,但我得到了重复的违规并且不明白如何。

这是我试图用来增加 order_no 的插入语句。

INSERT INTO patnotes (patkey, notetype, order_no)
SELECT FIRST 1 
    p.personkey, 
    'GEN' as notetype, 
    CASE WHEN n.order_no is null then 1 else (n.order_no + 1) end as order_no
FROM 
    person p 
LEFT JOIN 
    patnotes n 
    ON p.personkey = n.patkey 
    AND n.notetype = 'GEN'
WHERE 
    p.patid = '5000'
ORDER BY 
    n.order_no DESC

检查表是否存在以下条目

5000, GEN, 1
5000, GEN, 2

下一个顺序应该是 3。

运行上述插入语句的选择部分给出:

5000, GEN, 3

这是正确的,但不符合约束条件。如果我在第一个插入语句中手动输入这些,就没有问题。

现在下一个奇怪的问题是,如果我清除这些条目,那么第一个条目是 order_no 1。

这将为 order_no 1 和 2 添加条目,但对于 3+ 会失败,但如果我仅在插入语句中手动指定它,则没有问题。

我没有看到我错过的东西

informix
  • 1 1 个回答
  • 57 Views

1 个回答

  • Voted
  1. Best Answer
    Luís Marques
    2018-12-18T02:56:27+08:002018-12-18T02:56:27+08:00

    假设您使用的是最新的 12.10 Informix 版本,在线文档指出:

    如 INSERT 语句语法图中所示,并非 SELECT 语句的所有子句和选项都可供您在 INSERT 语句内的查询中使用。INSERT 语句不支持以下 SELECT 子句和选项:

    • 首先和限制
    • INTO TEMP、INTO RAW 和 INTO STANDARD 结果表选项
    • UNION、UNION ALL、INTERSECT、MINUS 和 EXCEPT 集合运算符。

    上下文中使用的语句FIRST不支持So。但是在查询中使用不会给出任何语法错误,所以可能发生了其他事情。SELECTINSERTFIRST

    -- The setup
    CREATE TABLE patnotes
    (
         patkey    SERIAL
        , notetype CHAR(4)
        , order_no INTEGER
    );
    
    CREATE UNIQUE INDEX patnotes_udx1 ON patnotes(patkey, notetype, order_no);
    
    INSERT INTO patnotes VALUES (5000, 'GEN', 1);
    INSERT INTO patnotes VALUES (5000, 'GEN', 2);
    
    CREATE TABLE person
    (
          personkey INTEGER
        , patid     CHAR(4)
    );
    
    INSERT INTO person VALUES (4999, '4999');
    INSERT INTO person VALUES (5000, '5000');
    INSERT INTO person VALUES (5001, '5001');
    
    -- The insert query
    INSERT INTO patnotes (patkey, notetype, order_no)
    SELECT FIRST 1 
        p.personkey
        , 'GEN' AS notetype
        , CASE 
            WHEN n.order_no IS NULL THEN 1 
            ELSE (n.order_no + 1) 
          END AS order_no
    FROM 
        person p 
    LEFT JOIN 
        patnotes n 
        ON p.personkey = n.patkey 
        AND n.notetype = 'GEN'
    WHERE 
        p.patid = '5000'
    ORDER BY 
        n.order_no DESC;
    

    当我们运行上面的代码时,INSERT我们得到:

    239: Could not insert new row - duplicate value in a UNIQUE INDEX column (Unique Index:patnotes_udx1).
    100: ISAM error:  duplicate value for a record with unique key.
    

    如果我们删除UNIQUE约束并运行INSERT多次,我们将始终获得相同的 column 值order_no。

    -- remove the UNIQUE
    DROP INDEX patnotes_udx1;
    
    -- Run the insert multiple times and we get
    SELECT * FROM patnotes;
    patkey notetype    order_no
    
      5000 GEN                1
      5000 GEN                2
      5000 GEN                2
      5000 GEN                2
      5000 GEN                2
      5000 GEN                2
      5000 GEN                2
      5000 GEN                2
      5000 GEN                2
      5000 GEN                2
    

    它不断插入相同的计算值order_no。似乎是一个错误。您应该使用 Informix 支持打开缺陷。

    作为解决方法,您可以使用MAX来计算order_no:

    INSERT INTO patnotes (patkey, notetype, order_no)      
    SELECT
        p.personkey
        , 'GEN' AS notetype
        , (MAX(NVL(n.order_no,0)) + 1) AS order_no
    FROM
        person p
    LEFT JOIN
        patnotes n
        ON p.personkey = n.patkey
        AND n.notetype = 'GEN'
    WHERE
        p.patid = '5000'
    GROUP BY
        p.personkey, notetype
    ;
    

    请注意,如果您有多个会话试图同时插入新值,这种方法将失败得很惨。您应该使用SERIAL或创建一个SEQUENCE来生成order_no值。

    • 2

相关问题

  • 给定以下规则,我应该如何最好地设计表和关系?

  • 尽管已关闭,但与 Informix 的连接仍处于活动状态?

  • 聚簇索引是否比预先排序加载文件和创建非聚簇索引提供更多好处?

  • Informix 的重叠

  • 如何删除名称不明确的程序?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve