LINUX.ORG.RU

Помогите понять SQL запрос

 , , ,


0

0

После upgrade до новой версии Skype, он segfault'ится на своей собственной базе.

На форуме приведено решение этой проблемы, но я хочу знать что оно делает:

UPDATE messages
   SET body_xml =( 
         SELECT SUBSTR( body_xml, files_start, alt_end - files_start ) ||
                SUBSTR( body_xml, 0, files_start ) || 
                SUBSTR( body_xml, alt_end )
           FROM ( 
             SELECT msg.body_xml,
                    instr( msg.body_xml, '<files' )  files_start,
                    instr( msg.body_xml, 'alt="' ) + 5 alt_end
               FROM messages msg
              WHERE msg.id = messages.id 
           ) 
       )
 WHERE type = 68 
   AND body_xml NOT LIKE '<file%';

Кто-нибудь на русском языке может объяснить как обновляются сообщения типа 68, не включающие в себя '<file%'?

Похоже что новая версия херит свою базу логов(сообщений). Сообщение в формате xml и должно начинаться с тега <files>. Но так как база похерилась, в ней похоже появились «сообщения» с неправильными тегами(возможно перед ним появился какой-нибудь «мусор») база неправильно считывается и скайп крошится. Соответственно этот запрос, находит такие мусорные «сообщения» и приводит их в «правильный» формат, т.е находит в «мусорном» сообщении тег «files» и считает сообщение уже от него, всё что было до этого, «мусорное» - отбрасывается. Примерно так.

xterro ★★★★★
()
Ответ на: комментарий от thespiritofbirdie

instr находит позицию подстроки в строке, SUBSTR извлекает подстроку из строки по указанным позициям.

Hater ★★
()
Ответ на: комментарий от thespiritofbirdie

Это всё круто, но откуда берутся переменные files_start, alt_end?

Из подзапроса

SELECT msg.body_xml,
                    instr( msg.body_xml, '<files' )  files_start,
                    instr( msg.body_xml, 'alt="' ) + 5 alt_end
               FROM messages msg
              WHERE msg.id = messages.id 

Что значит «+ 5 alt_end»?

instr находит начало вхождения подстроки. alt=" состоит из 5 символов, т.е. находится первый символ за этой подстрокой.

Hater ★★
()
Ответ на: комментарий от thespiritofbirdie

Это названия столбцов, в дальнейшем эти названи используются в вышестоящем запросе. Т.е запрос:

 SELECT msg.body_xml,
   instr( msg.body_xml, '<files' )  files_start,
   instr( msg.body_xml, 'alt="' ) + 5 alt_end
Вернёт таблицу с тремя стобцами: noname|files_start|alt_end. А вышестоящий запрос, т.е:
SELECT SUBSTR( body_xml, files_start, alt_end - files_start ) ||
                SUBSTR( body_xml, 0, files_start ) || 
                SUBSTR( body_xml, alt_end )
Для каждой записи из набора, берёт значение из столбцов files_start и alt_end и использует их для выполнения функции SubStr (в этих столбцах числа - позиции указанных подстрок)

xterro ★★★★★
()
Ответ на: комментарий от xterro

спасибо!

И последнее - этот SQL запрос обратим? Можно в случае чего его reverse'нуть?

Я просто не понимаю что конкретно он творит с сообщениями - страшно запускать :)

thespiritofbirdie
() автор топика
Ответ на: комментарий от thespiritofbirdie

Он влияет только на «битые» сообщения, целые он не трогает. Проще - копию файла сделай, если что не так, вернёшь старую версию.

xterro ★★★★★
()

похоже превращают записи из таких:

отправил (-а) файл &quot;id_dsa.pub&quot;<files alt=""><file size="609" index="0">id_dsa.pub</file></files>
в такие:
<files alt="отправил (-а) файл &quot;id_dsa.pub&quot;"><file size="609" index="0">id_dsa.pub</file></files>

bl ★★★
()
Ответ на: комментарий от thespiritofbirdie
$ sqlite3 main.db
sqlite> attach database 'messages-type68' as db2;
sqlite> CREATE TABLE db2.messages AS SELECT * FROM main.messages WHERE type = 68;
thespiritofbirdie
() автор топика
Ответ на: комментарий от thespiritofbirdie

Есть проблема с копированием файла с таким весом?

n04h
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.