За последние 24 часа нас посетили 17568 программистов и 1967 роботов. Сейчас ищут 786 программистов ...

Где ошибка?

Тема в разделе "MySQL", создана пользователем YulyaT, 27 авг 2012.

  1. YulyaT

    YulyaT Активный пользователь

    С нами с:
    11 июн 2012
    Сообщения:
    52
    Симпатии:
    0
    Пишу так:
    Код (Text):
    1. UPDATE Pix SET checked =1 WHERE idCategory=3 and idProducts=1 LIMIT 0,1
    не проходит.
    Так тоже не проходит
    Код (Text):
    1. UPDATE Pix SET checked =1 WHERE id = ( SELECT id FROM Pix WHERE idCategory =3 AND idProducts =1 LIMIT 0,1)
    Или всё дело в LIMIT 0,1?
    Пробую без LIMIT:
    Код (Text):
    1. update Pix set checked=1 where id=(SELECT id FROM Pix WHERE idCategory =3 AND idProducts =1 group by idCategory,idProducts)
    Тоже не работает, хотя это работает нормально
    Код (Text):
    1. SELECT id FROM Pix WHERE idCategory =3 AND idProducts =1 GROUP BY idCategory, idProducts
    и дает id.

    Вся задача:
    Есть таблица Pix, с колонками id,idCategory,idProducts и checked, все int(5).
    Проверяю для конкретных idCategory и idProducts поле checked, если 1 в какой-н строке, то ничего не делаю, если ноль, то только в первую строку нужно вставить checked =1
    Уникальные id+idCategory+idProducts, т.е. для разных id может быть много записей напр. idCategory =3 AND idProducts =1

    P.S. В MSSQL
    Код (Text):
    1. update pix set checked=1 where id=(SELECT top 1 id  FROM pix where idCategory=1 and idProduct=3 )
    великолепно работает, т.е. какая-то тонкость MySQL
     
  2. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    LIMIT 1.
    0,1 нету...

    И вообще тут он не нужен.
    У вас же конкретное условие WHERE проверяется!
     
  3. YulyaT

    YulyaT Активный пользователь

    С нами с:
    11 июн 2012
    Сообщения:
    52
    Симпатии:
    0
    1. На условие idCategory =3 AND idProducts =1 может быть 99999 записей.
    2. LIMIT 1 дает ошибку, а так
    Код (Text):
    1. SELECT id FROM Pix WHERE idCategory =3 AND idProducts =1 LIMIT 0,1
    работает.
     
  4. Dmitriy A. Arteshuk

    Dmitriy A. Arteshuk Активный пользователь

    С нами с:
    19 янв 2012
    Сообщения:
    2.445
    Симпатии:
    66
    Адрес:
    Зеленоград
    LIMIT 0,1 - выбрать 0 (НОЛЬ) записей со сдвигом в единицу...
     
  5. YulyaT

    YulyaT Активный пользователь

    С нами с:
    11 июн 2012
    Сообщения:
    52
    Симпатии:
    0
    limit 1 получаю
    #1093 - You can't specify target table 'Pix' for update in FROM clause
    в чём тонкость MySQL?
    В MSSQL такие конструкции работают без проблем
     
  6. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    По идее, так должно работать:
    Код (Text):
    1. UPDATE Pix SET checked = 1 WHERE idCategory = 3 AND idProducts = 1 LIMIT 1
    Если нет - то напиши текст сообщения об ошибке, которое от MySQL приходит.
    Не, наоборот. Первое число - сдвиг, второе - количество записей. Только я вот к своему удивлению обнаружил, что LIMIT в SELECT-запросах и LIMIT в UPDATE-запросах отличаются. В UPDATE нельзя два числа ставить через запятую (сдвиг указывать), можно только количество указать.
     
  7. YulyaT

    YulyaT Активный пользователь

    С нами с:
    11 июн 2012
    Сообщения:
    52
    Симпатии:
    0
    Очень странно, но сейчас работает.
    Давало ошибку, что таблица для поля checked не определена.
    Именно этот вариант в PHP у меня сохранился, сейчас update работает.
    Утром проверю несколько раз, не верю в чудеса.
    СПАСИБО!!
     
  8. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Скорее всего, в спешке была допущена какая-то ошибка - ну там букву лишнюю (но нужную) стёрли заодно с тем, что надо было стереть и не заметили или ещё что-нибудь в этом роде. Также возможно, например, что код отредактировали верно, но опять-таки в спешке - забыли залить его на сервер, и тестировали старый код с ошибкой, думая, что там исправленный - такое случается иногда :)
     
  9. YulyaT

    YulyaT Активный пользователь

    С нами с:
    11 июн 2012
    Сообщения:
    52
    Симпатии:
    0
    Всё работает сегодня, даже мой первый вариант
    Код (Text):
    1. SET @a=(SELECT count(0) FROM Pix  WHERE idCategory=3 and idProducts=1 and checked=1);
    2. UPDATE Pix SET checked=1 WHERE idCategory=3 AND idProducts=1 AND @a=0 LIMIT 1;
    Скорей всего, что в спешке что-то не так сделала:(
    Скажите, в принципе можно каким-то образом использовать select напрямую в условии update, т.е. без set?
    т.е. так:
    Код (Text):
    1. UPDATE Pix SET checked =1 WHERE idCategory =3 AND idProducts =1 AND
    2. (SELECT count(0) FROM Pix WHERE idCategory =3 AND idProducts =1 AND checked =1) =0 LIMIT 1 ;
    #1093 - You can't specify target table 'Pix' for update in FROM clause
    Насколько я понимаю, WHERE должен отработать до UPDATE и выяснить нужно ли его выполнять UPDATE согласно всех условий и почти уверена, что оптимизатор самого MySQL 2 мои строчки соединит в одну.
     
  10. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Как-то смутно понимаю, зачем вообще нужен тут этот SELECT... Можешь расписать? Объясни, чего хочешь добиться.
     
  11. YulyaT

    YulyaT Активный пользователь

    С нами с:
    11 июн 2012
    Сообщения:
    52
    Симпатии:
    0
    Чтобы апдейтить при условии, что нет таких записей.
     
  12. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.129
    Симпатии:
    1.249
    Адрес:
    там-сям
    это ад! проверь такой вариант:

    Код (Text):
    1. UPDATE Pix SET checked =1 WHERE idCategory =3 AND idProducts =1
    если бы это были мои таблицы, условие на idCategory тоже можно было бы выкинуть, а у вас не знаю как устроено )))
     
  13. YulyaT

    YulyaT Активный пользователь

    С нами с:
    11 июн 2012
    Сообщения:
    52
    Симпатии:
    0
    Ну я же выше ответила на этот вопрос.
    На условие idCategory =3 AND idProducts =1 может быть 99999 записей.
    Что значит " условие на idCategory тоже можно было бы выкинуть"?:)
    idCategory [1;99999] , idProducts [1;99999] и checked [1;99999]
    как устроенно описано выше
     
  14. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Тогда по идее оно не нужно. Достаточно и того варианта, который уже писали тут:
    Код (Text):
    1. UPDATE Pix SET checked = 1 WHERE idCategory = 3 AND idProducts = 1 LIMIT 1
    За счёт LIMIT 1 - у тебя будет обновляться только одна строка - это та строка, которая была бы первой, если бы мы написали
    Код (Text):
    1. SELECT * FROM Pix WHERE idCategory = 3 AND idProducts = 1 LIMIT 1
    Для большей уверенности в том, что это всегда будет одна и та же строка - можно добавить сортировку ORDER BY:
    Код (Text):
    1. UPDATE Pix SET checked = 1 WHERE idCategory = 3 AND idProducts = 1 ORDER BY id LIMIT 1
    Обновляться всегда будет только одна, первая строка, попадающая под твоё условие WHERE. И даже если в этой строке поле checked уже равно единице и при этом есть и другие строки с такими же idCategory и idProducts - просто ничего не обновится, поскольку в первой строке checked уже равен 1.
     
  15. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.129
    Симпатии:
    1.249
    Адрес:
    там-сям
    у таблицы Pix есть primary key или unique index ? по моему мнению условие WHERE должно однозначно задавать какие записи должны быть изменены — это проистекает из самого предназначения таблицы. это не сферический конь в вакууме, а неслучайная таблица для определенных целей.
    например:
    вариант а) если это таблица картинок про товар и у товара должна быть, одна картинка, то idProduct должен быть уникально проиндексирован и WHERE idProduct=1 гарантирует, что будет изменена строго одна запись.
    вариант б) то же самое, но у товара может быть несколько картинок разного размера. тогда должен быть уникальный индекс по (idProduct, idSize) типа того. и опять же нафиг не нужен LIMIT. я в WHERE задам однозначно определяющее условие. никаких блин уточняющих ORDER BY не надо. это не блядская пиздолпроеботина, а четкая и понятная таблица .

    понятно излагаю?

    Добавлено спустя 2 минуты 19 секунд:
    да что я тут усираюсь! читайте про "нормальные формы". это не догма, но выстраданные умными людьми на реальных задачах понятия.

    Добавлено спустя 1 минуту 48 секунд:
    ошибка в том, что начали писать без цели и плана