Oracle. Строковые и символьные функции

LENGTH

Syntax

length::=


Description of the illustration length.gif

Purpose

The functions return the length of . calculates length using characters as defined by the input character set.

Функция LENGTH

uses bytes instead of characters. uses Unicode complete characters. uses UCS2 code points. uses UCS4 code points.

can be any of the datatypes , , , , , or . The return value is of datatype . If has datatype , then the length includes all trailing blanks. If is null, then this function returns null.

Restriction on LENGTHB The function is supported for single-byte LOBs only. It cannot be used with and data in a multibyte character set.

Examples

The following example uses the function using a single-byte database character set:

SELECT LENGTH(‘CANDIDE’) «Length in characters» FROM DUAL; Length in characters ——————— 7

The next example assumes a double-byte database character set.

SELECT LENGTHB (‘CANDIDE’) «Length in bytes» FROM DUAL; Length in bytes ————— 14

Answers

Поэтому я хотел бы отделить строку самым дальним разделителем.

Я знаю, что это старый вопрос, но это простое требование, для которого достаточно СУБСТР и INSTR . REGEXP все еще медленнее и интенсивнее, чем старые функции subtsr и instr.

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

Вы подходите хорошо, но вы не указалиначальнуюпозицию в INSTR . Если начальная_позиция отрицательная , функция возвращает значение start_position числа символов из конца строки и затем выполняет поиск в начале строки.

Встроенные функции Oracle

У меня есть строка, и я хотел бы разделить эту строку на разделитель в определенной позиции.

Например, моя String — и результат, который я ищу, — это:

Поэтому я хотел бы отделить строку самым дальним разделителем.
Примечание. Некоторые из моих строк — это для которых мой SQL ниже работает отлично и возвращает желаемый результат.

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

и результат:

Почему это происходит и как я могу это исправить?

for flooders

Список Форумов  :: Не фоксом единым

   :: Помощь сайту :: 

Oracle. Проверка корректности формата дат
Pekpytep

Сообщений: 686
Откуда: Луганск

Всем привет.
Возникла необходимость проверки даты при импорте из csv в БД. Изобрел вот такой велосипед с квадратными колесами:
IF REGEXP_LIKE(v_employees(idx).birth_date, ‘%.%’) THEN v_employees(idx).birth_date := to_char(TO_DATE(v_employees(idx).birth_date, ‘DD.MM.YYYY’)); ELSIF REGEXP_LIKE(v_employees(idx).birth_date, ‘%/%’) THEN v_employees(idx).birth_date := to_char(TO_DATE(v_employees(idx).birth_date, ‘MM/DD/YYYY’)); END IF; BEGIN v_date := CAST(v_employees(idx).birth_date ASDATE); EXCEPTION WHEN OTHERS THEN v_employees(idx).birth_date := NULL; END; IF v_employees(idx).birth_date IS NULL THEN v_employees(idx).is_correct = 0; END IF;
Есть ли более простой способ проверить дату неизвестного формата в текстовом виде на корректность?

Pekpytep
проверить дату неизвестного формата в текстовом виде на корректность?

Строку неизвестного формата проверить невозможно в принципе. Как и трактовать её — что как дату, что как число…
Если ТОЧНО известно что могут быть такой, такой и вот такой форматы — это другое дело.

Oracle: получить длину частичного совпадения строк

Если форматы непротиворечивы то можно пытаться их разбирать.
В частности формат DD-MM-YYYY будет противоречить формату MM-DD-YYYY. Если в исходных данных может быть и то и это, то трактовать «как дату» такое нельзя — это гарантированно будет приводить к ошибкам. Не говоря уж о разновидностях с 2-значными годами…

P.S. В REGEXP_LIKE используется синтаксис регулярок, а не SQL-ного LIKE. Скажем для указанных двух форматов можно попробовать регулярки
‘[0-3]\d\.[0-1]\d\.[1-2]\d{3}’
и соответственно
‘[0-1]\d/[0-3]\d/[1-2]\d{3}’

Конечно же от 32 мая или от 13-го месяца, не говоря уж о 29 февраля в невисокосном году это не убережёт, поэтому to_date() надо и в этих случаях внутри блока с обработчиком ошибок применять.
Года я явно ограничил 1*** и 2***-ми. Можно и строже сделать, ограничив лишь 19** и 20**-ми.

——————

WBR, Igor

Re: Oracle. Проверка корректности формата дат
Pekpytep

Сообщений: 686
Откуда: Луганск

Igor Korolyov
Строку неизвестного формата проверить невозможно в принципе. Как и трактовать её

В принципе, я сторонник стандартизации файлообмена между подразделениями и организациями, но мое непосредственное начальство, к сожалению, считает иначе.

Igor Korolyov
Если ТОЧНО известно что могут быть такой, такой и вот такой форматы — это другое дело.

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

Igor Korolyov
В REGEXP_LIKE используется синтаксис регулярок, а не SQL-ного LIKE.

Да, стормозил. Подразумевал
v_employees(idx).birth_date := case when v_employees(idx).birth_date LIKE ‘%.%’ THEN to_char(TO_DATE(v_employees(idx).birth_date, ‘DD.MM.YYYY’)) … Через регексп тоже неплохо получилось, спасибо. Жаль что нет какой-нибудь интегрированной plsql функции для проверки корректности дат.

Ну функция конвертации как раз и выполняет проверку корректности
Правда между 2 января и 1 февраля записанными в разных форматах она, естественно, никак не сможет разобраться. Это я и имел в виду — 31.01 никогда «по ошибке» не превратится в 1 число 31-го месяца, а вот 01.02 — запросто.
Поэтому так опасно принимать на себя обязательства по разбору откровенного мусора. Кто будет крайним когда вылезет вот такая ерунда?

——————

WBR, Igor

On-line: 63 Sawradym Crispy of63 param ssa  and Guests: 58

В этом месяце родились:

AlexSSS(01)Goodwin(02)Sergey Fadeev(02)nnt64(03)newserg(04)Biskvit(05)bdv1983(05)vdstudio(06)Yla(06)victorsh(07)Kalmah(07)shumik73(07)Ji A(08)ИринаИ(09)vic7tar(10)ssa(11)Evil(12)yury mikitchuk(13)AleX_13(13)hotels(15)redline16(15)MaxPet(15)NickAssa(15)xeon(15)TRAKTORINA(17)dmitry_vil(18)Pazinich(18)dutchfox(18)panda(18)Root(19)Будрин(20)Grokasa(20)DenFROST(22)descent52(22)andreyyy(22)croacker(22)Аркадий(23)TaTT_DoGG(23)Zufir(25)ViKhaus(25)Сергей Зиньковский(28)rodini(28)bdv(28)


© 2000-2018 Fox Club&nbsp

sql перенос данных из одной таблицы в другую

Возникла следующая проблема: для некоторого приложения нужно было удалить поле tags = TaggableManager(blank=True) (и соответственно зависимость django-taggit). Как обычно, стираю это поле и вызываю makemigration, который сделал своё дело как надо. Но при вызове migrate для другого проекта с тем же набором миграций происходит ошибка, что приложение taggit не найдено для выполнения миграций. Оно, конечно, и логично, что миграции будут требовать это приложение.

Сейчас я понимаю, что просто можно было поправить миграции, где создавалось поле taggit и где оно удалялось, поэтому если вы так не сделали и у вас изменилась структура данных таблицы, то ниже описанные действия могут помочь.

Перенос данных из таблицы разной структуры

Допустим, у нас есть приложение projects и таблица projects_project с полями:

  1. id
  2. link (ссылка на страницу проекта)
  3. title_in_link (показываемая подсказка при наведении на ссылку)
  4. order (путь до картинки)
  5. border_color (цвет границы)
  6. tags (теги)

Мы хотим следующую структуру:

  1. id
  2. link
  3. hint
  4. order
  5. is_border
  6. border_color
  7. border_width

Тем самым мы видим следующие изменения:

  1. title_in_link переименовался в hint.
  2. Добавилось поле is_boder, при этом оно обязательно для заполнения.
  3. border_width, которое может быть пустым.
  4. Удалилось поле tags

А теперь «вручную» исправим структуру таблицы:

  1. Переименовываем таблицу: projects_project -> projects_project_old.
  2. Удаляем все миграции приложения, а также удаляем соответствующие записи миграций в таблице django_migrations в базе данных.

Чтобы удалить миграции определённых приложений в базе данных, я обычно захожу в pgadmin, нажимаю просмотр данных таблицы django_migrations, ввожу условие фильтрации, например:

app = ‘picture’ OR app = ‘gallery’ OR app = ‘file’

И удаляю все найденные строки.

  1. Вызываем makemigration для формирования 0001_initial.py (при этом понимаем, что придётся восстановить таблицу с помощью sql команд).
  2. Вызываем migrate и смотрим, что в базе данных создалась таблица projects_project с правильной структурой данных.
  3. Пишем sql код переноса данных из projects_project_old в projects_project:

INSERT INTO projects_project(id, link, hint, «order», is_border, border_color) select id, link, title_in_link, «order», ‘FALSE’, border_color from projects_project_old;

Проанализируйте пример: как видите, идёт соответствие полей для заполнения.

В интернете качественного примера я не нашёл, поэтому-то и родился сей пост, чтобы это дело восполнить 🙂

Обратите внимание, что border_width мы можем не заполнять, так как оно может быть пустым, а is_border мы должны заполнить, но, так как у нас нет информации об этом поле, то самое простое — это заполнить значением FALSE для каждой записи.

Oracle SQL- основные функции работы со строками

Как вариант потом можно написать django миграцию для заполнения полей TRUE или FALSE в зависимости от наличия какого-либо значения в поле border_color, но это уже другая история.

Ещё обратите внимание на то, что поле order совпадает со служебным словом sql, поэтому нужно это поле обособить двойными кавычками.

  1. Удаляем таблицу projects_project_old.

Вот, и всё. Ещё раз повторюсь, этот пример для тех, кто случайно сломал структуру данных таблицы, или миграции поломал или, таким образом как я, удалял зависимости от приложения. Это долгий «sql-ручной» путь исправления структуры, поэтому прежде чем удалять миграции, попробуйте их просто поправить 🙂

Перенос данных связанных таблиц

Допустим есть таблица: gallery и picture. Таблица picture содержит внешний ключ на таблицу gallery.

Этот случай немного по сложнее: при попытке выполнить 4 шаг описанный выше django скорее всего будет ругаться примерно так:

django.db.utils.ProgrammingError: relation «gallery_picture_6d994cdb» already exists

Для решения проблемы нужно переименовать индекс:

ALTER INDEX public.gallery_picture_6d994cdb RENAME TO gallery_picture_old_6d994cdb;

Это можно сделать через графический интерфейс pgadmin:

Нужный нам индекс выделен зелёным. Теперь правой кнопкой мыши по щелчку на индекс вызываем контекстное меню и выбираем свойства:

Здесь нужно переименовать индекс, например, дописав «_old».

Теперь снова пытаемся выполнить шаг 4 и далее следуем остальным выше описанным шагам.

Оцените статью

Автор статьи

Мальцев Артём

Веб-разработчик, владеющий знаниями языка программирования Python, фреймворка Django, системы управления содержимым сайта Django CMS, платформы для создания интернет-магазина Django Shop и многих различных приложений, использующих эти технологии.

Права на использование данной статьи, расположенной на настоящей странице http://vivazzi.ru/it/sql-move-data-in-different-tables/:

Разрешается копировать статью с указанием её автора и ссылки на оригинал без использования параметра в теге . Использование:

Автор статьи: Мальцев Артём
Ссылка на статью: <a href="http://vivazzi.ru/it/sql-move-data-in-different-tables/">http://vivazzi.ru/it/sql-move-data-in-different-tables/</a>

Подробнее: Правила использования сайта

Вам нужно саморазвиваться или вы хотите зарабатывать деньги?

Или вы ищите хорошие IT сервисы или книги? Сохраните свое время и взгляните на мою подборку рекомендаций, которыми постоянно пользуюсь.
Посмотреть рекомендации

Добавить комментарий

Закрыть меню