powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / вопрос о DUPLICATE KEY UPDATE
16 сообщений из 16, страница 1 из 1
вопрос о DUPLICATE KEY UPDATE
    #38907604
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
INSERT
..... ON DUPLICATE KEY UPDATE

как можно узнать что было сделано?
INSERT или UPDATE?
last_insert_id не предлагать.
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907605
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяlast_insert_id не предлагать.что так?
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907617
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftвадяlast_insert_id не предлагать.что так?
поля id (c его прибамбасами )нет
так нада... :)
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907619
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если запись вставляется только одна (а не пачка), то last_insert_id все еще может помочь.
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907625
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft,

у меня ast_insert_id всегда 0
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907637
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну можно запросить COUNT(*) до и после... а нах... зачем?
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907647
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для такова изврата :)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
BEGIN
  SET @ip = INET_ATON('178.156.133.188');
  SET @x = 0;
  SET @login = 'user';
  SET @password = 'admin1';
  SET @pl = 0;
  SET @m = 0;
  SET @y = 0;
  INSERT INTO mo.access (ip, n, t)
    VALUE (@ip, 0, 0)
  ON DUPLICATE KEY UPDATE
  n = (SELECT
      @x := v.nn
    FROM (SELECT
        @a := UNIX_TIMESTAMP() - t,
        CASE WHEN @a < 10 THEN @m := n + 1 WHEN @a < 30 THEN @m := 3 WHEN @a >= 30 THEN @m := 0 END AS nn,
        CASE WHEN @m < 3 THEN @pl := (SELECT
                  COUNT(users.id) AS n
                FROM users
                WHERE users.login = @login
                AND users.password = @password) END,
        @y := 1
      FROM mo.access
      WHERE ip = @ip) AS v),
  t = CASE WHEN @x < 3 THEN UNIX_TIMESTAMP() ELSE t END;

  

  IF @y = 0 THEN
    SELECT
      COUNT(users.id) INTO @pl
    FROM users
    WHERE users.login = @login
    AND users.password = @password;
  END IF;


  SELECT
    @pl
  ;


но желательно избавиться от if в конце....
ну и упростиь, если можно...
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907731
Stupid_BOT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторно желательно избавиться от if в конце....
ну и упростиь, если можно...
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
  {skipped}
  INSERT INTO mo.access (ip, n, t)
  VALUES (@ip, 0, UNIX_TIMESTAMP())
  ON DUPLICATE KEY UPDATE
    n = @n:= CASE 
        WHEN (@a:= VALUES(t) - t) < 10 THEN n+1 
        WHEN @a < 30 THEN 3 
        ELSE 0 
    END,
    t = CASE 
        WHEN n < 3 THEN VALUES(t) 
        ELSE t 
    END;
  
  SET @p1:= CASE
      WHEN 1 = ROW_COUNT() OR @n < 3 THEN (
        SELECT COUNT(users.id)
        FROM users
        WHERE users.login = @login
        AND users.password = @password 
      )
      ELSE 0
  END;  
  SELECT @p1;

...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907807
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stupid_BOT,
этот вариант я делал. у него один дефект - сначала всегда происходит insert , а если ip новый то проверки на логин , пароль не происходит.
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907811
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадя,
sory, с телефона не рассмотрел, предложенный вариант интересен, похож на мой - состоит их из двух частей, хочется из одной.
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38907849
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадя , было бы правильным не только показать код, но и разъяснить идею, которая за ним прячется.
На всякий случай вот тебе идея - работает даже для INSERT ... SELECT ... ON DUPLICATE KEY UPDATE ...

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
mysql> CREATE TABLE test (id INT PRIMARY KEY, val INT);
Query OK, 0 rows affected (0.18 sec)

mysql> INSERT INTO test (id,val)
    -> SELECT 1,1 UNION ALL
    -> SELECT 2,1 ;
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test;
+----+------+
| id | val  |
+----+------+
|  1 |    1 |
|  2 |    1 |
+----+------+
2 rows in set (0.05 sec)

mysql> DELIMITER |
mysql> CREATE TRIGGER au_test AFTER UPDATE ON test
    ->   FOR EACH ROW BEGIN
    ->     SET @upd = @upd  + 1;
    ->   END; |
Query OK, 0 rows affected (0.06 sec)

mysql> CREATE TRIGGER ai_test AFTER INSERT ON test
    ->   FOR EACH ROW BEGIN
    ->     SET @ins = @ins + 1;
    ->   END; |
Query OK, 0 rows affected (0.06 sec)

mysql> DELIMITER ;

mysql> SET @upd = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> SET @ins = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO test (id,val) VALUES (1,1) ON DUPLICATE KEY UPDATE val = val + 1;
Query OK, 2 rows affected (0.02 sec)

mysql> SELECT @upd, @ins;
+------+------+
| @upd | @ins |
+------+------+
|    1 |    0 |
+------+------+
1 row in set (0.00 sec)

mysql> SELECT * FROM test;
+----+------+
| id | val  |
+----+------+
|  1 |    2 |
|  2 |    1 |
+----+------+
2 rows in set (0.00 sec)

mysql> SET @upd = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> SET @ins = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO test (id,val) VALUES (3,1) ON DUPLICATE KEY UPDATE val = val + 1;
Query OK, 1 row affected (0.02 sec)

mysql> SELECT @upd, @ins;
+------+------+
| @upd | @ins |
+------+------+
|    0 |    1 |
+------+------+
1 row in set (0.00 sec)

mysql> SELECT * FROM test;
+----+------+
| id | val  |
+----+------+
|  1 |    2 |
|  2 |    1 |
|  3 |    1 |
+----+------+
3 rows in set (0.00 sec)

mysql> SET @upd = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> SET @ins = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO test (id,val)
    -> SELECT 1,1 UNION ALL
    -> SELECT 4,1
    -> ON DUPLICATE KEY UPDATE val = val + 1;
Query OK, 3 rows affected (0.03 sec)
Records: 2  Duplicates: 1  Warnings: 0

mysql> SELECT @upd, @ins;
+------+------+
| @upd | @ins |
+------+------+
|    1 |    1 |
+------+------+
1 row in set (0.00 sec)

mysql> SELECT * FROM test;
+----+------+
| id | val  |
+----+------+
|  1 |    3 |
|  2 |    1 |
|  3 |    1 |
|  4 |    1 |
+----+------+
4 rows in set (0.07 sec)
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38908158
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,
идея в том чтоб производить проверку логин/пароль и исключить подбор их . допускается три попытки в течении 10 сек, потом 30 сек игнорирования проверки, т.е. логин/пароль принимаютя, но не происходит запроса к базе, внешне это выглядит как будто всё проверяется.(времена пока с потолка, чтоб прверять не долго было). Мой вариант работает, но хочется проще ,за один запрос. в таблице n это число проделанных попыток.
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38908168
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
возвращает 1 если есть такой юзер , 0 в любом другом случае, даже если в 30 секундном интервеле введен правильный пароль/логин
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38908245
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что за синтаксиис
WHEN (@a:= VALUES(t) - t) < 10 THEN n+1
я в мануалах не смог найти
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38908260
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадя,

про values - здесь

а данный фрагмент записывает в переменную @a разность между вставляемым и имевшимся значениями, и если она меньше 10, то возвращает n+1
...
Рейтинг: 0 / 0
вопрос о DUPLICATE KEY UPDATE
    #38910481
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
боле логичный вариант
даётся 3 попытки, после 3 не правильных попыток делается пауза в 30 секунд (можно любое время) в течении которого возвращается количество попыток (они же и записываются в n), в таблицу так же записывается время время последней не правильной попытки. при неправильных попытках (> 3) обращение к таблице юзеров не происходит, поэтому даже правильная попытка будет проигнорирована.
таблицу access можно сделать в памяти (только надо следить за её размером) и тогда перебор логин/пароль не будет сильно грузить железо.

таблица
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE TABLE access (
  ip int(12) UNSIGNED NOT NULL DEFAULT 0,
  n int(11) NOT NULL DEFAULT 0,
  t bigint(20) NOT NULL DEFAULT 0,
  PRIMARY KEY (ip),
  UNIQUE INDEX UK_access_ip (ip)
)
ENGINE = INNODB
AVG_ROW_LENGTH = 8192
CHARACTER SET utf8
COLLATE utf8_general_ci;



хранимка
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
CREATE DEFINER = 'root'@'localhost'
PROCEDURE mo.procedure1(IN ip varchar(15), IN login varchar(20), IN password varchar(20), OUT access int)
BEGIN

  SET @login = login;
  SET @password = `password`;
  SET @a = UNIX_TIMESTAMP();

  INSERT INTO access (ip, n, t)
    VALUE (INET_ATON(ip), 0, 0)
  ON DUPLICATE KEY UPDATE
  n = @access := CASE WHEN (n < 3) OR
        (@a - t) > 30 THEN CASE WHEN (SELECT
                  COUNT(users.id)
                FROM users
                WHERE users.login = @login
                AND users.password = @password) = 1 THEN 0 ELSE n + 1 END ELSE n + 1 END,
  t = CASE WHEN n >= 3 THEN @a ELSE 0 END;

  IF 1 = ROW_COUNT() THEN
    SELECT
      IF(COUNT(users.id) = 0, 1, 0) INTO @access
    FROM users
    WHERE users.login = @login
    AND users.password = @password;
  END IF;

  SET access = @access;

END

...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / вопрос о DUPLICATE KEY UPDATE
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]