Вставка условной строки SQL - PullRequest
4 голосов
/ 18 мая 2010

Можно ли вставить новую строку, если выполняется условие?

Например, у меня есть эта таблица без первичного ключа и уникальности

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

Я хотел бы вставить строку, если комбинация image_id и tag_id не существует например;

INSERT ..... WHERE image_id!=39 AND tag_id!=8

Ответы [ 6 ]

7 голосов
/ 18 мая 2010

Я думаю вы говорите: вам нужно избегать повторяющихся строк в этой таблице.

Есть много способов справиться с этим. Один из самых простых:

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, вы можете использовать проверочное ограничение для объединенных столбцов, но тогда вам понадобится блок 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(); 
    }
}

Нет практического способа проверить дубликаты на более ранних этапах процесса, потому что другой пользователь может пометить фильм в любой момент, поэтому нет способа обойти это.

Примечание: Если попытка вставить запись дублирования означает, что есть ошибка, тогда выдается ошибка, но если нет, вам не нужны дополнительные сложности в обработчике ошибок.

0 голосов
/ 19 июля 2013
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'
    );
0 голосов
/ 18 мая 2010

Тариф на кредит Хенрик Опе l, когда он заметил то, что мы все пропустили, включая меня, простое уникальное ограничение на две колонки. В конечном счете, это лучшее решение.

0 голосов
/ 18 мая 2010

Если вы используете InnoDB с транскрипциями, вы можете сначала просто запросить данные, а затем в своем коде выполнить вставку, если теперь уже найдены строки со значениями. В качестве альтернативы добавьте уникальное содержимое над обоими столбцами и попробуйте вставить. Если не удастся, если он уже существует, который вы можете игнорировать. (Это менее предпочтительно, чем мой первый подход.)

0 голосов
/ 18 мая 2010

Я предполагаю, что вы хотите вставить строку, если она не содержит этих значений.

У меня нет 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)
0 голосов
/ 18 мая 2010

Попробуйте использовать триггер базы данных для эффективного способа добавления строк в другую таблицу на основе обновлений таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...