Подтвердить что ты не робот

Вставить и установить значение с помощью max() + 1 проблем

Я пытаюсь вставить новую строку и установить client_id с max() + 1. Причина этого в таблице уже имеет auto_increatment в другом столбце с именем id, и таблица будет иметь несколько строк с тем же customer_id.

При этом:

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  ((SELECT MAX( customer_id ) FROM customers) +1, 'jim', 'sock')

... Я продолжаю получать следующую ошибку:

#1093 - You can't specify target table 'customers' for update in FROM clause

Также как бы остановить одновременное добавление двух разных клиентов и не иметь того же client_id?

4b9b3361

Ответ 1

Правильно, вы не можете изменять и выбирать из той же таблицы в том же запросе. Вы должны выполнить вышеуказанное в двух отдельных запросах.

Лучший способ - использовать транзакцию, но если ваш не использовать таблицы innodb, то лучше всего блокировать таблицы, а затем выполнять ваши запросы. Итак:

Lock tables customers write;

$max = SELECT MAX( customer_id ) FROM customers;

Захватите максимальный id, а затем выполните вставку

INSERT INTO customers( customer_id, firstname, surname )
VALUES ($max+1 , 'jim', 'sock')

unlock tables;

Ответ 2

Вы можете использовать оператор INSERT ... SELECT, чтобы получить значение MAX()+1 и одновременно вставить:

INSERT INTO 
customers( customer_id, firstname, surname )
SELECT MAX( customer_id ) + 1, 'jim', 'sock' FROM customers;

Note: You need to drop the [TG43] from your [TG44] and make sure the [TG45] selected fields match the [TG46] declared fields.

Ответ 3

Используйте псевдоним для внутреннего запроса, подобного этому

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  ((SELECT MAX( customer_id )+1 FROM customers cust), 'sharath', 'rock')

Ответ 4

SELECT MAX(col) +1 небезопасен - он не гарантирует, что вы не вставляете более одного клиента с тем же значением customer_id, независимо от выбора из той же таблицы или любых других. правильный способ обеспечить уникальное целочисленное значение присваивается при вставке в вашу таблицу в MySQL, это использовать AUTO_INCREMENT. Стандарт ANSI - использовать последовательности, но MySQL их не поддерживает. Столбец AUTO_INCREMENT может быть определен только в инструкции CREATE TABLE:

CREATE TABLE `customers` (
  `customer_id` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(45) DEFAULT NULL,
  `surname` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`customer_id`)
)

Тем не менее, это сработало для меня в 5.1.49:

CREATE TABLE `customers` (
  `customer_id` int(11) NOT NULL DEFAULT '0',
  `firstname` varchar(45) DEFAULT NULL,
  `surname` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$

INSERT INTO customers VALUES (1, 'a', 'b');

INSERT INTO customers 
SELECT MAX(customer_id) + 1, 'jim', 'sock'
  FROM CUSTOMERS;

Ответ 5

insert into table1(id1) select (max(id1)+1) from table1;

Ответ 6

Использовать псевдоним таблицы в подзапросе:

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  ((SELECT MAX( customer_id ) FROM customers C) +1, 'jim', 'sock')

Ответ 7

Ни один из ответов на вопрос не работает для моего случая. Я получил ответ от здесь, и мой SQL:

INSERT INTO product (id, catalog_id, status_id, name, measure_unit_id, description, create_time)
VALUES (
  (SELECT id FROM (SELECT COALESCE(MAX(id),0)+1 AS id FROM product) AS temp),
  (SELECT id FROM product_catalog WHERE name="AppSys1"),
  (SELECT id FROM product_status WHERE name ="active"),
  "prod_name_x",
  (SELECT id FROM measure_unit WHERE name ="unit"),
  "prod_description_y",
  UNIX_TIMESTAMP(NOW())
)

Ответ 8

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

Ответ 9

Объявляем переменную 'a'

SET **@a** = (SELECT MAX( customer_id ) FROM customers) +1;

INSERT INTO customers
  ( customer_id, firstname, surname )
VALUES 
  (**@a**, 'jim', 'sock')

Ответ 10

Mine - это вставка, но вот что я в итоге использовал здесь.

update
   m
set
   m.host_id = max(h.host_id)
from
   t_po_master as m
   inner join t_al_host_po_master as h on m.po_number = h.po_number
where
   m.host_id is NULL
   and m.client_code = '01'

EDIT - Это действительно не сработало. Я не уверен, почему нет, так как превращение его в инструкцию select выглядит так, что это сработает, но это обновит все host_ids до одного и того же идентификатора. Поэтому я бы не использовал это, это хороший пример.

Ответ 11

Это выбрать и вставить продолжение.

Я пытаюсь получить серийное максимальное значение +1 и его правильное значение.

SELECT MAX(serial_no)+1 into @var FROM sample.kettle;
Insert into kettle(serial_no,name,age,salary) values (@var,'aaa',23,2000);

Ответ 12

Ваш подзапрос просто неполный, вот и все. Смотрите запрос ниже с моими пристрастиями:

INSERT INTO customers ( customer_id, firstname, surname ) 
VALUES ((SELECT MAX( customer_id ) FROM customers) +1), 'jim', 'sock')