Вставка с условием на COUNT - PullRequest
3 голосов
/ 28 декабря 2010

Как я могу построить запрос MySQL INSERT, который только выполняется, если число строк, удовлетворяющих некоторому условию уже в таблице, меньше 20, и в противном случае происходит сбой?

То есть, если в таблице 18 строк, удовлетворяющих условию, то INSERT должен продолжаться. Если в таблице 23 строки, удовлетворяющих условию, вставка должна завершиться неудачей.

Для атомарности мне нужно выразить это в одном запросе, поэтому два запроса не могут ВСТАВИТЬ одновременно, каждый в «убеждении», что только 19 строк удовлетворяют условию.

Спасибо.

Ответы [ 4 ]

7 голосов
/ 28 декабря 2010

А как же:

INSERT INTO TargetTable(Column1, Column2, ...)
    SELECT 'Value For Column 1', 'Value For Column 2', ...
      FROM Dual
     WHERE (SELECT COUNT(*) FROM TargetTable WHERE ...Some Condition...) < 20;

Если предложение WHERE не выполнено, строка не вставляется; если условие where выполнено, вставляется одна строка.

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

1 голос
/ 28 декабря 2010

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

LOCK TABLES t WRITE;

perform count

decide - to insert or not in your programming language

UNLOCK TABLES;
0 голосов
/ 28 декабря 2010

Единственный известный мне способ получить запрос для фактического выброса ошибки - это использовать команду SIGNAL - которая доступна только в MySQL 5.5 внутри хранимых процедур.

Допустимо ли создавать хранимую процедуру для воплощения этой задачи? Если это так, то можно делать то, что вы хотите.

В противном случае единственный вариант - запустить два запроса - один для проверки количества строк, а другой для вставки новых строк, если строк достаточно для выполнения вашего условия.

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

0 голосов
/ 28 декабря 2010
declare @varaibleOne int;

WAITFOR DELAY '00:00:02';
select
@varaibleOne=SUM(case when (condition satisfied) then 1 else 0 end)
from table where (if you have anything)

IF(@varaibleOne<=20)
begin
insert into table ()
end

Ожидание заявления не точно .. Вы можете погуглить его ..

...