Как предотвратить ошибку недопустимых символов в SQL-запросе DB2?

Я работаю с огромной таблицей DB2 (сотни миллионов строк), пытаясь выбрать только те строки, которые соответствуют этому регулярному выражению:

\b\d([- \/\\]?\d){12,15}(\D|$)

(То есть граница слова, за которой следуют от 13 до 16 цифр, разделенных ничем или одним тире, пробелом, косой чертой или обратной косой чертой, за которыми следует либо нецифра, либо конец строки.)

После долгих поисков в Google мне удалось создать следующий SQL:

SELECT idx, comment FROM tblComment
WHERE xmlcast(xmlquery('fn:matches($c,"\b\d([- \/\\]?\d){12,15}(\D|$)")' PASSING comment AS "c") AS INTEGER)=1

Что работает отлично, насколько я могу судить... если не находит строку с недопустимым символом:

В выражении SQL/XML или аргументе функции, начинающемся [...]

Данные содержат много недопустимых XML-символов, и изменение данных невозможно (у меня ограничен доступ только для чтения, и слишком много строк нужно исправить). Есть ли способ удалить или игнорировать недопустимые символы без предварительного изменения базы данных? Или есть другой способ написать мой запрос, который имеет тот же эффект?


person ArmanX    schedule 24.02.2016    source источник
comment
Какова кодовая страница вашей базы данных?   -  person Ian Bjorhovde    schedule 25.02.2016
comment
Понятия не имею. Я новичок в DB2, плюс у меня нет контроля и очень мало доступа к базе данных. Есть ли запрос, который я могу запустить, чтобы узнать? Я могу запустить его, как только вернусь в офис завтра утром.   -  person ArmanX    schedule 25.02.2016
comment
кодовый набор и кодовую страницу можно запросить таким образом, выберите * из sysibmadm.dbcfg, где имя похоже на «код%», в противном случае обратитесь к своему администратору баз данных.   -  person MichaelTiefenbacher    schedule 25.02.2016
comment
Кодовая страница: 1252; кодовый набор: IBM-1252   -  person ArmanX    schedule 25.02.2016


Ответы (1)


Вам нужно будет определить все недопустимые символы XML, встречающиеся в ваших данных. Как только вы их узнаете, вы можете использовать функцию TRANSLATE(), чтобы исключить их во время сопоставления с образцом.

Скажем, вы определяете, что все управляющие символы ASCII (от 0x00 до 0x0F и 0x7F) могут присутствовать в столбце COMMENT. Тогда ваш запрос может выглядеть так:

SELECT idx, comment FROM tblComment
WHERE xmlcast(xmlquery(
  'fn:matches($c,"\b\d([- \/\\]?\d){12,15}(\D|$)")' 
  PASSING TRANSLATE(comment, ' ', x'01020304050607080B0C0F7F') AS "c") 
AS INTEGER)=1

Все допустимые символы XML: перечислены в руководстве. 0x09, 0x0A и 0x0D допустимы, поэтому, например, вам не нужно их TRANSLATE().

person mustaccio    schedule 03.03.2016