суббота, 19 мая 2012 г.

Oracle, генерация случайной даты и случайной строки

Если нам надо проверить какую-либо задачу на "а упадешь ли ты, если долго работать придется?", то надо откуда-то взять кучу данных, впоследствии отдаваемых задаче на обработку.

Создавать данные "извне" как-то уныло, клепать в каком-нибудь экселе 1 000 000 строк. Хотя, при помощи макросов, почему бы и нет?

Но если есть доступ к базе, почему бы не сделать это напрямую к ней? Итак, допустим, у нас есть таблица Авторов (В своих примерах я обычно ссылаюсь на БД с авторами книг). И нам надо сгенерировать 4 млн записей с разными ФИО и датами рождения. При этом каждые 4 автора должны быть идентичными. Как это сделать?

Генерация случайной строки.

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

DBMS_RANDOM.STRING (p_type, p_len)


Первый параметр, p_type, отпределяет тип генерируемой строки

Значение p_typeДействие
u
Генерировать только буквы в верхнем регистре (например,
DFTHNDSW)
l
Генерировать только буквы в нижнем регистре (например,
pikdcdsd)
aГенерировать только буквы в обоих регистрах (например, DeCW- Cass)
x
Генерировать буквы и цифры в верхнем регистре (например,
A1W56RTY)
PГенерировать любые печатные символы (например, $\$2sw&*)


Второй параметр, p_len, отпределяет длину генерируемой строки.

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

Итого, чтобы сгенерировать строку длиной от 3 до 5 символов в верхнем регистре, используем команду

DBMS_RANDOM.STRING ('x', DBMS_RANDOM.VALUE (3,5))

Генерация случайной даты.

Для того, чтобы сгенерировать случайную дату, возьмем команду sysdate, которая возвращает текущую системную дату и вычтем из нее какое-нибудь логичное значение.
Возьмем промежуток времени в 50 лет до текущей даты. 50 лет на 365 дней в году = 18250 дней. Запишем дату рождения автора:

  days := DBMS_RANDOM.VALUE (1, 18250);
  birth := sysdate - days;

Пример скрипта для генерации большого числа дубликатов.
Отдельные значения мы получили, теперь надо написать сам скрипт.

declare
  id number;
  days number;
  birth date;
  name nvarchar2(5);
  surname nvarchar2(10);
  patronymic nvarchar2(25);
begin
   
  for i in 1..10000000 loop
   
  days := DBMS_RANDOM.VALUE (1, 18250);
  birth := sysdate - days;
  name := DBMS_RANDOM.STRING ('x', DBMS_RANDOM.VALUE (3,5));
  surname := DBMS_RANDOM.STRING ('x', DBMS_RANDOM.VALUE (7,10));
  patronymic := DBMS_RANDOM.STRING ('x', DBMS_RANDOM.VALUE (10,25));
   
    for j in 1..4 loop
     
      select author_seq.nextval into id from dual;
           
      insert into author (ID_AUTHOR, SURNAME, NAME, PATRONYMIC, BIRTHDATE)
      values (id, surname, name, patronymic, birth);
    end loop;
     
    if mod(i, 1000) = 0 then
      commit;
    end if;
  end loop;
  commit;
end;

Вначале раздел declare - объявляем все переменные, которые будут использованы ниже.
Во внешнем цикле устанавливаем значения для ФИО и даты рождения и во внутреннем цикле вставляем их в таблицу. Для id используем команду nextval, чтобы идентификатор автора был уникальным. 

Внутренний цикл прогоняется, создав 4 одинаковых авторов, потом значения ФИО и ДР обновляется на новое рандомное значение, и так по кругу. 

ВАЖНО!!!
Отладка скрипта под свою таблицу БД осуществляется на внешнем цикле i = 5

Комментариев нет:

Отправить комментарий