MYSQL использование CONCAT и SUBSTRING с URL-адресами http и https в базе данных - PullRequest
0 голосов
/ 02 мая 2018

Этот вопрос вращается вокруг использования CONCAT и SUBSTRINGS для ОБНОВЛЕНИЯ содержимого в mysql TABLE

Если у меня есть ссылка, хранящаяся в базе данных mysql, которая состоит из

https://this.example.com/work-a-link.php?https://that.example.com/thisisworthkeeping.php

Следующий код удалит первый экземпляр и оставит второй экземпляр URL с префиксом http: // url (хотя в теории в этом случае это должен быть https: // - так как второй URL начинался с https://

DROP TABLE IF EXISTS content_temp;
CREATE TABLE content_temp AS SELECT * FROM content GROUP BY Title ORDER BY ID ASC;
UPDATE content_temp SET link = CONCAT('http://', SUBSTRING_INDEX(link, 'https://', -1));
UPDATE content_temp SET link = CONCAT('http://', SUBSTRING_INDEX(link, 'http://', -1));
UPDATE content_temp SET link=replace(link,'http://https://','http://');
UPDATE content_temp SET link=replace(link,'http://http://','http://');

И в этом проблема, я ищу помощи кого-то, кто может помочь мне или указать мне правильное направление - я хочу, чтобы любой https:// во втором случае был оставлен как https:// - тогда как мой обоюдный код меняется на http://

Чего я хочу добиться, так это уважать и хранить любой второй экземпляр - будь то http ИЛИ https.

Единственный другой случайный фактор во всем этом ... это то, что первым экземпляром может быть http ИЛИ https

Таким образом, конечный результат перенастройки этого кода будет:

(А)

http://this.example.com/work-a-link.php?http://that.example.com/thisisworthkeeping.php 

даст http://that.example.com/thisisworthkeeping.php.

(В)

http://this.example.com/work-a-link.php?https://that.example.com/thisisworthkeeping.php 

даст https://that.example.com/thisisworthkeeping.php.

(С)

https://this.example.com/work-a-link.php?http://that.example.com/thisisworthkeeping.php 

даст http://that.example.com/thisisworthkeeping.php.

и

(Д)

https://this.example.com/work-a-link.php?https://that.example.com/thisisworthkeeping.php 

даст https://that.example.com/thisisworthkeeping.php.

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Похоже, у вас есть четыре возможных комбинации, на которые мы смотрим. Первый может быть либо «http» или «https», а второй может быть «http» или «https». Четыре возможных комбинации:

http:/  http:/
http:/  https:/
https:/ http:/
https:/ https:/

Пара предложений:

Во-первых, перед тем, как выполнить оператор UPDATE, в котором мы не уверены, что он собирается делать то, что намеревается сделать, нам нужно написать оператор SELECT в test выражений. Это позволит нам увидеть результаты выражения, чтобы мы могли убедиться, что оно выполняет то, к чему мы стремимся, в различных условиях тестирования.

Во-вторых, должна быть возможность выделить комбинации (четыре возможности). Если изменения, которые мы применяем, «удаляют» первые http / https, оставляя только одно вхождение ... тогда модификация, которую мы применяем к одному из подмножеств, не сделает строку, а затем перейдет в другое подмножество. (Я понял, что я хотел сказать там, это, вероятно, натолкнулось на искаженное.)

Если у меня есть такая строка

http 1   https 2 

и я изменяю это с обновлением на

https 2 

Затем последующий прогон по строкам, который не будет совпадать с проверкой для

https  https 

потому что в строке есть только одно вхождение http.


Предположим, что нас интересуют только строки, в которых строка link содержит два вхождения http:// / https://

Мы могли бы использовать регулярное выражение для некоторого сопоставления, или мы можем выдумать его с некоторыми LIKE сравнениями

SELECT t.link
     , t.link LIKE '%http://%http://%'   AS c1 
     , t.link LIKE '%http://%https://%'  AS c2 
     , t.link LIKE '%https://%http://%'  AS c3 
     , t.link LIKE '%https://%https://%' AS c4
  FROM (

SELECT 'http://somedomain.com/work-a-link.php?http://someotherdomain.com/thisisworthkeeping.php' AS link
UNION ALL
SELECT 'http://somedomain.com/work-a-link.php?https://someotherdomain.com/thisisworthkeeping.php'
UNION ALL
SELECT 'https://somedomain.com/work-a-link.php?http://someotherdomain.com/thisisworthkeeping.php'
UNION ALL 
SELECT 'https://somedomain.com/work-a-link.php?https://someotherdomain.com/thisisworthkeeping.php'

       ) t
 WHERE t.link LIKE '%http%://%http%://%'
   AND t.link NOT LIKE '%http%://%http%://%http%://%'  

возвращает что-то вроде этого (с некоторой заменой строки в значениях ссылки, чтобы сократить их здесь) ...

link                                                           c1  c2  c3  c4
-------------------------------------------------------------- --  --  --  --
http://somedomain.com/walp?http://someotherdomain.com/tiwkp     1   0   0   0
http://somedomain.com/walp?https://someotherdomain.com/tiwkp    0   1   0   0
https://somedomain.com/walp?http://someotherdomain.com/tiwkp    0   0   1   0
https://somedomain.com/walp?https://someotherdomain.com/tiwkp   0   0   0   1

Мы включили условие в предложение WHERE, чтобы «отфильтровывать» любой URL, где существует более двух вхождений «http [s]: //». (Там есть небольшая путаница, подстановочный знак % может совпадать с любым количеством символов, поэтому мы не совсем проверяем HTTPS: // и http: // ... (опять же, мы могли бы реализовать обычный выражение выражения (REGEXP или RLIKE), чтобы быть более точным.

Но обратите внимание, как нам удалось «классифицировать» ссылку на значения на c1, c2, c3 и c4.

Подтверждение того, что каждая ссылка попадает в одну категорию, Мы можем включить дополнительное выражение в список SELECT

     , CASE 
       WHEN t.link LIKE '%http://%http://%'   THEN 'c1'
       WHEN t.link LIKE '%http://%https://%'  THEN 'c2'
       WHEN t.link LIKE '%https://%http://%'  THEN 'c3' 
       WHEN t.link LIKE '%https://%https://%' THEN 'c4'
       ELSE NULL
       END

Если мы находим подходящее условие WHEN, мы возвращаем THEN, и все готово. (Если есть перекрытие, ссылка, которая попадает в более чем одну категорию, мы не увидим ее в этом выражении.)

link                                                            c   c1  c2  c3  c4
-------------------------------------------------------------- --  --  --  --  --
http://somedomain.com/walp?http://someotherdomain.com/tiwkp    c1   1   0   0   0
http://somedomain.com/walp?https://someotherdomain.com/tiwkp   c2   0   1   0   0
https://somedomain.com/walp?http://someotherdomain.com/tiwkp   c3   0   0   1   0
https://somedomain.com/walp?https://someotherdomain.com/tiwkp  c4   0   0   0   1

Мы можем тестировать с различными значениями link, различными шаблонами и проверять, что наша подходящая «категоризация» работает так, как мы намереваемся.

(Этот метод использования оператора SELECT для проверки выражений и особенно функций, с которыми мы не знакомы ... с SUBSTRING_INDEX, что возвращается, когда строка поиска не найдена? Чувствительна ли к регистру функция REPLACE? И и так далее.)

Мы можем настраивать и настраивать, экспериментировать и находить правильные комбинации, чтобы все работало так, как мы хотим. Как только мы получим это,

Мы можем включить еще одно выражение в список SELECT. Мы скопируем только что добавленное, но на этот раз вместо возврата литерала мы добавим другое выражение, которое выполняет функции SUBSTRING_INDEX и REPLACE.

Поскольку мы запускаем SELECT, мы знаем, что не собираемся искажать / изменять содержимое таблицы. Мы просто тестируем некоторые выражения, чтобы увидеть, что они возвращают.

     , CASE 
       WHEN t.link LIKE '%http://%http://%'    -- 'c1'
       THEN CONCAT('http://', SUBSTRING_INDEX(t.link, 'http://', -1))

       WHEN t.link LIKE '%http://%https://%'   -- 'c2'
       THEN CONCAT('https://', SUBSTRING_INDEX(t.link, 'https://', -1))

       WHEN t.link LIKE '%https://%http://%'   -- 'c3' 
       THEN CONCAT('http://', SUBSTRING_INDEX(t.link, 'http://', -1))

       WHEN t.link LIKE '%https://%https://%'  -- 'c4'
       THEN CONCAT('https://', SUBSTRING_INDEX(t.link, 'https://', -1))

       ELSE NULL
       END AS new_link

И довольно скоро мы получим такой результат ...

link                                                           new_link 
-------------------------------------------------------------  ---------------------------------
http://somedomain.com/walp?http://someotherdomain.com/tiwkp    http://someotherdomain.com/tiwkp
http://somedomain.com/walp?https://someotherdomain.com/tiwkp   https://someotherdomain.com/tiwkp
https://somedomain.com/walp?http://someotherdomain.com/tiwkp   http://someotherdomain.com/tiwkp
https://somedomain.com/walp?https://someotherdomain.com/tiwkp  https://someotherdomain.com/tiwkp

Как только у нас работает работающее выражение, которое возвращает значение new_link, которое мы хотим присвоить столбцу, вместо значения link,

(и мы сначала запустим тестовую копию таблицы)

Мы можем преобразовать наш оператор SELECT в ОБНОВЛЕНИЕ

заменить SELECT ... FROM на UPDATE

и добавьте предложение SET, чтобы назначить выражение new_link для ссылки

(замените NULL в ELSE ссылкой на столбец, чтобы в случае, если мы выполним все условия, которые мы проверяем в CASE, мы не будем изменять эту строку ...)

UPDATE mytesttable t
   SET t.link
     = CASE 
       WHEN t.link LIKE '%http://%http://%'    -- 'c1'
       THEN CONCAT('http://', SUBSTRING_INDEX(t.link, 'http://', -1))

       WHEN t.link LIKE '%http://%https://%'   -- 'c2'
       THEN CONCAT('https://', SUBSTRING_INDEX(t.link, 'https://', -1))

       WHEN t.link LIKE '%https://%http://%'   -- 'c3' 
       THEN CONCAT('http://', SUBSTRING_INDEX(t.link, 'http://', -1))

       WHEN t.link LIKE '%https://%https://%'  -- 'c4'
       THEN CONCAT('https://', SUBSTRING_INDEX(t.link, 'https://', -1))

       ELSE t.link
       END
 WHERE t.link LIKE '%http%://%http%://%'  
   AND t.link NOT LIKE '%http%://%http%://%http%://%'  

Но прежде чем запустить UPDATE, мы должны протестировать наши выражения с различными значениями ссылок, включая крайние и угловые регистры.

И еще раз обратите внимание, что те сравнения LIKE, которые я написал, потенциально могут совпадать со шаткими строками, которые мы, возможно, не хотим сравнивать, например. http://BLAH http DERP :// flurb http://.

Похоже, что мы должны также проверять вопросительный знак перед вторым появлением http.

Мы бы получили более точное сопоставление с образцом, используя регулярные выражения, сравнение с REGEXP (RLIKE).


Тема остается прежней ... сначала протестируйте выражения с помощью SELECT, а затем запустите ОБНОВЛЕНИЕ.

0 голосов
/ 02 мая 2018

Если все ваши ссылки, которые будут изменены, содержат подстроку .php?, вы можете сделать это:

UPDATE content_temp SET link = SUBSTRING_INDEX(link, '.php?', -1)
      WHERE link LIKE '%.php?%'

Совет для профессионалов: Всегда полезно помещать предложение WHERE в операцию UPDATE: без этого SQL обновляет все строки в таблице. Это может испортить таблицу и затопить журнал транзакций.

...