Oracle SQL - генерировать уникальное имя sAMAccountName - PullRequest
0 голосов
/ 13 ноября 2018

Я хотел бы использовать Oracle SQL для генерации уникального sAMAccountName для пользователей.Логика генерации уникального имени - это первая буква имени + полное имя.

Если комбинация уже существует, добавьте 1 в конце уникального имени.Если вторая комбинация уже существует, приращение до уникальности будет достигнуто.

Например, 5 пользователей с именем "Tom Kelly" и 3 пользователя с именем "Tom Ke" будут иметь следующие уникальные имена:

  1. TKelly
  2. TKelly1
  3. TKelly2
  4. TKelly3
  5. TKelly4
  6. TKe
  7. TKe1
  8. TKe2

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

SELECT SUBSTR(Custom_Unique_Name,-1,1) INTO lastletter 
FROM (SELECT * FROM (SELECT Custom_Unique_Name FROM 
P_USERS WHERE Custom_Unique_Name= item.tempid2 AND 
user_id <> item.user_id ORDER BY Custom_Unique_Name 
DESC) WHERE ROWNUM<=1);

Таблица только для чтения P_USERS содержит всех пользователей с первичным ключом как "user_id", и уникальное имя сохраняетсяв атрибуте "Custom_Unique_Name"

После вычисления уникального имени необходимо обновить атрибут "PRIMARY_UNIQUE_NAME" в основной таблице пользователя "T_MASTER_USERS".Первичный ключ этой таблицы также "user_id", который содержит то же значение, что и в таблице только для чтения "P_USERS"

   DECLARE
    lastletter varchar2(10);
    anyexists varchar2(10);
    lastfive varchar2(10);
    CURSOR c_length IS SELECT SUBSTR(first_name,1,1)||(last_name) as 
    tempid2,LENGTH(last_name) as lengthln, user_id, Custom_Unique_Name 
    FROM P_USERS;
    status varchar2(10);
    BEGIN
     FOR item in c_length
      LOOP
        EXIT WHEN c_length%notfound;
        lastletter:=0;
        SELECT NVL(Custom_Unique_Name,0) INTO status FROM P_USERS 
        WHERE USER_ID=item.user_id; 
        IF status <> '0' THEN /* Checks if the person already has a 
        unique id */
         NULL;   /* If yes, then do nothing and exit the program */
        ELSE
            SELECT COUNT(*) INTO anyexists FROM (SELECT 
            Custom_Unique_Name FROM P_USERS 
            WHERE Custom_Unique_Name = item.tempid2 AND user_id <> 
            item.user_id);
            IF anyexists=0 THEN     /* Check if unique id exists for 
            the user. If not, then assign unique_id to the user */
                UPDATE T_MASTER_USERS SET 
                PRIMARY_UNIQUE_NAME=item.tempid2 WHERE 
                user_id=item.user_id;
                ELSE
                 SELECT SUBSTR(Custom_Unique_Name,-1,1) INTO lastletter 
                 FROM (SELECT * FROM (SELECT Custom_Unique_Name FROM 
                 P_USERS WHERE Custom_Unique_Name= item.tempid2 AND 
                 user_id <> item.user_id ORDER BY Custom_Unique_Name 
                 DESC) WHERE ROWNUM<=1);
                 IF LENGTH(TRIM(TRANSLATE(lastletter, ' 
                 +-.0123456789',' '))) > 0 THEN /* Checks if the count 
                 of equivalent unique names if a number. If not, append 
                 1*/
                    UPDATE T_MASTER_USERS SET 
                    PRIMARY_UNIQUE_NAME=item.tempid2||'1' WHERE 
                    user_id=item.user_id;
                    ELSE
                     lastletter:=lastletter+1;
                     UPDATE T_MASTER_USERS SET 
                     PRIMARY_UNIQUE_NAME=item.tempid2||lastletter WHERE 
                     user_id=item.user_id;
                  END IF;
                END IF;
            END IF;
        END LOOP;
      END;

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

Попробуйте ниже анонимный блок для вашего сценария:

  create table P_USERS
     (first_name varchar2(20),
     last_name   varchar2(20),
     user_id   number);

  insert into P_USERS values ('Tom','Kelly',1);
 insert into P_USERS values ('Tom','Kelly',2);
 insert into P_USERS values ('Tom','Kelly',3);
 insert into P_USERS values ('Tom','Kelly',4);
 insert into P_USERS values ('Tom','Kelly',5);
 insert into P_USERS values ('Tom','Ke',6);
 insert into P_USERS values ('Tom','Ke',7);
 insert into P_USERS values ('Tom','Ke',8);
 commit;

 create table T_MASTER_USERS
 ( user_id   number,
 PRIMARY_UNIQUE_NAME varchar2(20));

  insert into T_MASTER_USERS values (1,NULL);
 insert into T_MASTER_USERS values (2,NULL);
 insert into T_MASTER_USERS values (3,NULL);
 insert into T_MASTER_USERS values (4,NULL);
 insert into T_MASTER_USERS values (5,NULL);
 insert into T_MASTER_USERS values (6,NULL);
 insert into T_MASTER_USERS values (7,NULL);
 insert into T_MASTER_USERS values (8,NULL);
 commit;


 DECLARE
    cursor uniq_grp is SELECT SUBSTR(first_name,1,1)||(last_name) as 
    tempid2 ,count(*) as CNT
    FROM P_USERS
    group by SUBSTR(first_name,1,1)||(last_name);

    cursor concat_names is SELECT SUBSTR(first_name,1,1)||(last_name) as 
    tempid2, user_id 
    FROM P_USERS;

    V_CNT number;

 BEGIN

    FOR C1 in uniq_grp

    LOOP

    FOR C2 IN concat_names
    LOOP
    IF C2.tempid2=C1.tempid2 THEN 
     V_CNT := c1.CNT -1;
    UPDATE T_MASTER_USERS SET 
      PRIMARY_UNIQUE_NAME=c2.tempid2||V_CNT WHERE 
       user_id=C2.user_id;
       c1.cnt := V_CNT;
    END IF;
    END LOOP;

    COMMIT;

    END LOOP;

END;
0 голосов
/ 20 ноября 2018

создать или заменить процедуру generate_unique (par_first_name в varchar2, par_last_name в varchar2) (par_first_name в varchar2, par_last_name в varchar2)
есть
l_username users.username% type;
l_letter users.username% type;

начало

 l_username := upper(substr(par_first_name, 1, 1) || par_last_name); 

 dbms_output.put_line('l_username = ' || l_username );  

ВЫБРАТЬ СЛУЧАЙ, КОГДА МАКС. (REGEXP_REPLACE (ВЕРХНИЙ (ИМЯ ПОЛЬЗОВАТЕЛЯ), '[^ 0-9]', '')) НЕДЕЙСТВИТЕЛЕН

            THEN l_username 

            ELSE l_username 

                    || 

                    (MAX(REGEXP_REPLACE(UPPER(USERNAME),'[^0-9]', ''))+1) 

    END into l_letter FROM    USERS WHERE   REGEXP_LIKE(UPPER(USERNAME),l_username||'[0-9]*$'); 

dbms_output.put_line ('уникальный идентификатор пользователя' || l_letter);
конец;

0 голосов
/ 13 ноября 2018

Как насчет этого?

SQL> create table users
  2    (username varchar2(20) primary key);

Table created.

SQL> create or replace procedure p_un (par_first_name in varchar2,
  2                                    par_last_name  in varchar2)
  3  is
  4    l_username users.username%type;
  5    l_letter   users.username%type;
  6    l_digit    users.username%type;
  7    retval     users.username%type;
  8  begin
  9    l_username := upper(substr(par_first_name, 1, 1) || par_last_name);
 10
 11    select max(regexp_substr(u.username, '^\w+')) l_letter,
 12           max(regexp_substr(u.username, '\d+$')) l_digit
 13      into l_letter,
 14           l_digit
 15      from users u
 16      where u.username like l_username ||'%'
 17        and (   substr(u.username, length(l_username) + 1, 1) between '1' and '9'
 18             or (    regexp_substr(u.username, '\d$') is null
 19                 and substr(u.username, length(l_username) + 1, 1) is null
 20                )
 21            )
 22        and (   to_number(regexp_substr(username, '\d$')) =
 23                 (select max(to_number(regexp_substr(u1.username, '\d$')))
 24                  from users u1
 25                  where u1.username like l_username ||'%'
 26                  and (   substr(u1.username, length(l_username) + 1, 1) between '1' and '9'
 27                       or (    regexp_substr(u1.username, '\d$') is null
 28                           and substr(u1.username, length(l_username) + 1, 1) is null
 29                          )
 30                      )
 31                 )
 32              or regexp_substr(u.username, '\d$') is null
 33             );
 34
 35    if l_letter is null then
 36       retval := upper(l_username);
 37    else
 38       retval := upper(l_username || to_char(to_number(nvl(l_digit, 0)) + 1));
 39    end if;
 40
 41    dbms_output.put_line('l_username = ' || l_username||', letter = '|| l_letter||
 42                         ', digit = '||l_digit ||', new username = ' || retval);
 43    insert into users (username) values (retval);
 44  end;
 45  /

Procedure created.

Что это делает?

SELECT (в строке 11) ищет существующие имена пользователей, которые

  • выглядит как новое имя пользователя (которое состоит из первой буквы имени и всей фамилии) (строка 16)
  • содержит число в конце (строка 17)
  • или номер вообще отсутствует (строки 18, 19)
  • но, если там есть номер, выберите МАКС. Номер (строка 23)
  • если такого имени пользователя не существует, вернуть его значение по умолчанию (строка 36)
  • если он существует, добавьте 1 к номеру MAX и присоедините его к значению имени пользователя по умолчанию (строка 38)

Тестирование:

SQL> exec p_un('Tom', 'Kelly');
l_username = TKELLY, letter = , digit = , new username = TKELLY

PL/SQL procedure successfully completed.

SQL> exec p_un('Tom', 'Kelly');
l_username = TKELLY, letter = TKELLY, digit = , new username = TKELLY1

PL/SQL procedure successfully completed.

SQL> exec p_un('Tom', 'Kelly');
l_username = TKELLY, letter = TKELLY1, digit = 1, new username = TKELLY2

PL/SQL procedure successfully completed.

SQL> exec p_un('Tom', 'Ke');
l_username = TKE, letter = , digit = , new username = TKE

PL/SQL procedure successfully completed.

SQL> exec p_un('Tom', 'Ke');
l_username = TKE, letter = TKE, digit = , new username = TKE1

PL/SQL procedure successfully completed.

SQL> exec p_un('Tom', 'Kelly');
l_username = TKELLY, letter = TKELLY2, digit = 2, new username = TKELLY3

PL/SQL procedure successfully completed.

SQL> exec p_un('Tom', 'Ke');
l_username = TKE, letter = TKE1, digit = 1, new username = TKE2

PL/SQL procedure successfully completed.

SQL> exec p_un('Tom', 'Ke');
l_username = TKE, letter = TKE2, digit = 2, new username = TKE3

PL/SQL procedure successfully completed.

Результат:

SQL> select * From users;

USERNAME
--------------------
TKE
TKE1
TKE2
TKE3
TKELLY
TKELLY1
TKELLY2
TKELLY3

8 rows selected.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...