#sql #oracle
#sql #Oracle
Вопрос:
У меня есть существующая таблица с данными, которые являются varchar. Эти коды были предварительно определены кем-то другим, поэтому я не могу их изменить.
Каждый год мне нужно будет запускать инструкцию insert, которая принимает данные / коды предыдущего года и переносит их с новым годом на них.
Пример существующих данных, используемых за 2019 год: CodeA19, CodeB19, CodeC19, CodeE19 и т. Д
Что мне нужно сделать, так это последовательно добавлять 1 к каждому коду, чтобы изменить его на новый год (в данном случае на 2020): CodeA20, CodeB20, CodeC20, CodeE20 и т. Д
Я пытался выполнить поиск регулярных выражений для этого, но самостоятельно мне не повезло. Кажется, я не могу найти способ выделить смешанные значения для добавления в числовую последовательность.
Oracle db, PL sql, используя SQL Dev
Спасибо!
Комментарии:
1. Вы хотите выбрать все строки с кодами, заканчивающимися на 19, и вставить их снова с кодом, заканчивающимся на 20?
Ответ №1:
Вы могли бы использовать регулярное выражение, чтобы найти значения, заканчивающиеся на предыдущий год, извлечь оставшуюся часть и привязать к новому году; с жестко закодированными значениями что-то вроде:
select regexp_replace(code, '(.*)19$', '1') as root,
regexp_replace(code, '(.*)19$', '1') || '20' as result
from your_table
where regexp_like(code, '(.*)19$');
или на основе фактического текущего года, предполагая, что вы запускаете его в течение нового года:
select regexp_replace(code, '(.*)' || to_char(add_months(sysdate, -12), 'RR') || '$', '1') as root,
regexp_replace(code, '(.*)' || to_char(add_months(sysdate, -12), 'RR') || '$', '1')
|| to_char(sysdate, 'RR') as result
from your_table
where regexp_like(code, '(.*)' || to_char(add_months(sysdate, -12), 'RR') || '$');
оба из которых в настоящее время получают:
ROOT RESULT
---------- ----------
CodeA CodeA20
CodeB CodeB20
CodeC CodeC20
CodeE CodeE20
а затем использовать это как вставку:
insert into your_table (code)
select regexp_replace(code, '(.*)' || to_char(add_months(sysdate, -12), 'RR') || '$', '1')
|| to_char(sysdate, 'RR') as result
from your_table
where regexp_like(code, '(.*)' || to_char(add_months(sysdate, -12), 'RR') || '$');
Шаблон регулярных выражений немного наивен, но работает для примеров; если у вас есть более сложные значения, которые могут привести к сбою, или вы хотите сопоставить только определенные префиксы, тогда вам нужно будет это адаптировать.
Если единственными числами являются двузначные годы в конце, тогда вы могли бы упростить использование replace
вместо regexp_replace
, как предложил Гордон:
insert into your_table (code)
select replace(code, to_char(add_months(sysdate, -12), 'RR'), to_char(sysdate, 'RR')) as result
from your_table
where code like to_char(add_months(sysdate, -12), '"%"RR');
… но это может быть большим «если».
Комментарии:
1. Спасибо всем, кто предложил помощь. Я думаю, мне нужно быть более ясным, тип кода — это не слово code, это было только для буквенно-цифрового примера. В них содержится несколько сотен кодов с разными именами, примеры: abdcef19 bedef19 aofdjkle19 asljenvidke19, поэтому выполнение регулярного выражения для замены одного альфа-значения не сработает. Единственной переменной, которая всегда будет оставаться постоянной, является год, который отображается как 19 (для 2019), 20 (для 2020) и т.д. Есть мысли? Я пытаюсь доказать это в будущем для себя и для всех, кому я мог бы это передать.
2. Алекс, ваша инструкция replace сработала с одной заминкой, которую я сначала не заметил, около 13 моих «кодов» также содержат символы после года, пример: ABCD19 против ABCD19Q1
3. Я не предполагал, что в значении был ‘code’, но я выбрал ‘code’ в качестве фиктивного имени столбца, что могло сбить с толку. Если у вас все еще есть только номера лет и кварталов, так что вы можете безопасно заменить все двузначные значения, то я думаю, что просто измените конечный термин с
'"%"RR'
на'"%"RR"%"'
. Или, опять же, вы можете выполнять более сложные проверки с помощью регулярных выражений, чтобы включить и сохранить четвертную часть, но, похоже, в этом нет необходимости.4. @ScottReschke RR похож на YY, но переносит проблему Y2K на середину века.
5. @WilliamRobertson — мы должны пережить эпоху 2039 года -сначала alypse * 😎
Ответ №2:
Вероятно, самый простой метод replace
:
update t
set code = replace(code, '19', '20')
where code like '';
Это предполагает, что коды не имеют номеров.
Примечание: это кажется очень странной моделью данных, если вы меняете существующие значения в соответствии с этим.