代码之家  ›  专栏  ›  技术社区  ›  Pablo

SQL条件行插入

  •  4
  • Pablo  · 技术社区  · 14 年前

    如果条件满足,是否可以插入新行?

    例如,我有一个没有主键和唯一性的表

        +----------+--------+
        | image_id | tag_id |
        +----------+--------+
        |    39    |    8   |
        |    8     |    39  |
        |    5     |    11  |
        +----------+--------+
    

    如果图像和标记的组合不存在,我想插入一行 例如;

    INSERT ..... WHERE image_id!=39 AND tag_id!=8
    
    6 回复  |  直到 11 年前
        1
  •  7
  •   egrunin    14 年前

    认为 您的意思是:您需要避免此表中的重复行。

    有很多方法可以解决这个问题。最简单的方法之一:

    INSERT INTO theTable (image_id, tag_id) VALUES (39, 8)
    WHERE NOT EXISTS 
        (SELECT * FROM theTable 
        WHERE image_id = 39 AND tag_id = 8)
    

    正如@henrik opel指出的那样,您可以在组合的列上使用check约束,但是您必须在其他地方使用try/catch块,这增加了不相关的复杂性。

    编辑 解释这个评论…

    我假设这是一个映射电影和标签之间多对多关系的表。我知道您可能在使用PHP,但我希望下面的C伪代码足够清晰。

    如果我有 Movie 类,添加标记最自然的方法是 AddTag() 方法:

    class Movie 
    {
        public void AddTag(string tagname)
        {
            Tag mytag = new Tag(tagname); // creates new tag if needed
    
            JoinMovieToTag(this.id, mytag.id);
        }
    
        private void JoinMovieToTag(movie_id, tag_id)
        {
            /* database code to insert record into MovieTags goes here */
    
            /* db connection happens here */
            SqlCommand sqlCmd = new SqlCommand("INSERT INTO theTable... /* etc */");
    
            /* if you have a check constraint on Movie/Tag, this will 
               throw an exception if the row already exists */
            cmd.ExecuteNonQuery(); 
        }
    }
    

    在这个过程的早期,没有切实可行的方法来检查重复,因为另一个用户可能随时标记电影,所以没有办法解决这个问题。

    注: 如果试图插入重复记录意味着存在错误,那么抛出一个错误是合适的,但如果不是,您不希望在错误处理程序中有额外的复杂性。

        2
  •  0
  •   Marcus Adams    14 年前

    尝试使用数据库触发器,以便根据表的更新向其他表添加行。

        3
  •  0
  •   Dan    14 年前

    我假设您的意思是,如果行不包含这些值,您希望插入一行。

    我前面没有MySQL,但一般来说,SQL应该可以工作:

    INSERT INTO a_table (image_id, tag_id) SELECT ? image_id, ? tag_id WHERE  image_id!=39 AND tag_id!=8
    

    如果只在根本不存在这样的行的情况下插入行,则可以这样做:

    INSERT INTO a_table (image_id, tag_id) SELECT ? image_id, ? tag_id WHERE not exists (SELECT 1 from a_table WHERE image_id!=39 AND tag_id!=8)
    
        4
  •  0
  •   mdma    14 年前

    如果您使用的是innodb和transactions,那么您可以先简单地查询数据,然后在代码中执行insert if now行已经找到了值。或者,在两列上添加一个唯一的constaint,然后尝试插入。如果会失败,如果它已经存在,您可以忽略它。(这比我的第一种方法更不可取。)

        5
  •  0
  •   Community kfsone    7 年前

    是车费吗 Henrik Ope 当他发现我们都忽略的东西时,包括我在内,这两个列上有一个简单的独特约束。最终是最好的解决方案。

        6
  •  0
  •   Nanhe Kumar    11 年前
    To avoid duplicate row insertion use the below mentioned query:
    
    INSERT INTO `tableName` ( `image_id`, `tag_id`)
    SELECT `image_id`, `tag_id` FROM `tableName`
    WHERE NOT EXISTS (SELECT 1
        FROM `tableName`
        WHERE `image_id` = '39'
        AND `tag_id` = '8'
        );