2015-10-28 4 views
0

У меня есть кусок кода SQL, взятый из хранимой процедуры Elmah под SQL Server:Как написать этот конкретный запрос в mysql?

DELETE FROM [ELMAH_Error] 
WHERE ErrorId NOT IN (SELECT TOP 100 ErrorId FROM ELMAH_Error ORDER BY TimeUtc DESC) 

я теперь мигрировать веб-сайт, чтобы использовать MySQL вместо этого, и я не знаю, как перевести этот код.

Я должен добавить перевод после этого фрагмента кода:

CREATE DEFINER=`b43638b86659eb`@`%` PROCEDURE `elmah_LogError`(
    IN ErrorId CHAR(36), 
    IN Application varchar(60), 
    IN Host VARCHAR(30), 
    IN Type VARCHAR(100), 
    IN Source VARCHAR(60), 
    IN Message VARCHAR(500), 
    IN User VARCHAR(50), 
    IN AllXml TEXT, 
    IN StatusCode INT(10), 
    IN TimeUtc DATETIME 
) 
    MODIFIES SQL DATA 
BEGIN 
    INSERT INTO `elmah_error` (
     `ErrorId`, 
     `Application`, 
     `Host`, 
     `Type`, 
     `Source`, 
     `Message`, 
     `User`, 
     `AllXml`, 
     `StatusCode`, 
     `TimeUtc` 
    ) VALUES (
     ErrorId, 
     Application, 
     Host, 
     Type, 
     Source, 
     Message, 
     User, 
     AllXml, 
     StatusCode, 
     TimeUtc 
    ); 
END 

Я пытался добавить @ ответ Sick непосредственно перед утверждением END, но SQL Workbench (по альтер команды процедуры) не видит его.

Благодаря

ответ

1

Эквивалент Sql Server TOP Ключевое слово в Mysql является Limit, и она должна быть в конце запроса

DELETE FROM `ELMAH_Error` 
WHERE ErrorId NOT IN (SELECT ErrorId 
         FROM `ELMAH_Error` 
         ORDER BY TimeUtc DESC LIMIT 100) 
+0

Это близко, чтобы исправить, хотя вы должны использовать обратные кавычки вместо скобок ('[...]') вокруг имени таблицы. –

+0

@ EdCottrell - Yep пропустил это :) –

+0

Спасибо @Sick. Я обновил свой вопрос, чтобы показать вам трудности, с которыми я пытаюсь ваше решение. –

0

MySQL не поддерживает limit в некоторых подзапросов. Если это тот случай, а затем использовать явное присоединиться:

DELETE e 
    FROM ELMAH_Error e LEFT JOIN 
     (SELECT ErrorId 
      FROM ELMAH_Error 
      ORDER BY TimeUtc DESC 
      LIMIT 100 
     ) ee 
     ON ee.ErrorId = e.ErrorId 
    WHERE ee.ErrorId IS NULL; 

EDIT:

Приведенный выше код предполагает, что ErrorId является уникальным в таблице, и не имеет значения NULL. Если это неверно, запрос не будет работать. (Примечание: предположение о том, что столбец под названием Id является уникальным и непустым кажется, очень разумно.)

DELETE e 
    FROM ELMAH_Error e LEFT JOIN 
     (SELECT TimeUtc 
      FROM ELMAH_Error 
      ORDER BY TimeUtc DESC 
      LIMIT 100 
     ) ee 
     ON ee.TimeUtc = e.TimeUtc 
    WHERE ee.TimeUtc IS NULL; 
+0

Этот код принят сервером MySql. Я проверил, что генерация ошибки не была нарушена. Это не. Что касается удаления записей, я смогу проверить, что он работает позже, когда ошибки складываются. Тем временем я буду отмечать ваше решение как ответ. –

+0

Кажется, что проблема в конце концов. Этот код хранит только одну запись в моей таблице ошибок! Есть идеи? –

+0

@NicolasCadilhac. , , Это произойдет, когда самые последние 100 строк имеют одинаковый 'ErrorId'. –

0

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

lock tables ELMAH_Error write; 
create temporary table cpy_ELMAH_Error 
    select * from ELMAH_Error order by TimeUtc DESC LIMIT 100; 
truncate table ELMAH_Error; 
insert into ELMAH_Error select * from cpy_ELMAH_Error; 
drop table cpy_ELMAH_Error; 
unlock tables; 
+0

Спасибо. Сейчас он не большой, и он будет расти до 100 записей. После этого DELETE гарантирует, что не будет превышать 100. –

0

Существует еще один способ несколько проще, если вы заинтересованы:

set @N=0; 
delete from ELMAH_Error where (@N:[email protected]+1) > 101 order by TimeUtc DESC; 
+0

Я все еще ищу решение.Я попробовал ваш, и он ничего не удаляет. Есть идеи? –