根据表名称同步SEQUENCE / TRIGGER名称

时间:2017-03-06 10:47:59

标签: oracle automation

我使用different question thread中给出的答案中的代码,根据表名创建序列和触发器。

但是,我的表格非常接近(或已经达到)30个字符的限制,因此我收到此错误:

Error report:
ORA-00972: identifier is too long
ORA-06512: at line 15
00972. 00000 -  "identifier is too long"
*Cause:    An identifier with more than 30 characters was specified.
*Action:   Specify at most 30 characters.

我的问题是,我如何连接表名,以便他们不会抛出这个错误,仍然保留标题中的一些表名?也许连续到20个字符和" _SEQ"或" _TRIG"最后?

这是我的代码:

DECLARE
  CURSOR TABLES
  IS
    SELECT *
    FROM USER_TABLES
    WHERE 0 =
      (SELECT COUNT(*)
      FROM USER_CONSTRAINTS
      WHERE USER_CONSTRAINTS.TABLE_NAME    = USER_TABLES.TABLE_NAME
      AND USER_CONSTRAINTS.CONSTRAINT_TYPE = 'P'
      );
BEGIN
  FOR T IN TABLES
  LOOP
    EXECUTE IMMEDIATE 'CREATE SEQUENCE '||T.TABLE_NAME||'_SEQ START WITH 1';
    EXECUTE IMMEDIATE 'UPDATE '||T.TABLE_NAME||' SET ID = '||T.TABLE_NAME||'Seq.NEXTVAL';
    EXECUTE IMMEDIATE 'ALTER TABLE '||T.TABLE_NAME||' ADD PRIMARY KEY (ID)';
    EXECUTE IMMEDIATE 'CREATE OR REPLACE TRIGGER '||T.TABLE_NAME||'_TRIG '||CHR(10) ||'BEFORE INSERT ON '||T.TABLE_NAME||' '||CHR(10) ||'FOR EACH ROW '||CHR(10) ||'BEGIN '||CHR(10) ||':NEW.ID := '||T.TABLE_NAME||'Seq.NEXTVAL; '||CHR(10) ||'END; ';
  END LOOP;
END;
/

1 个答案:

答案 0 :(得分:0)

这将使用删除元音的表名(然后取名字的前25个字符,如果你的表名恰好超过25个字符且元音很少)。

DECLARE
  CURSOR TABLES
  IS
    SELECT *
    FROM USER_TABLES
    WHERE 0 =
      (SELECT COUNT(*)
      FROM USER_CONSTRAINTS
      WHERE USER_CONSTRAINTS.TABLE_NAME    = USER_TABLES.TABLE_NAME
      AND USER_CONSTRAINTS.CONSTRAINT_TYPE = 'P'
      );
  t_name VARCHAR2(30);
BEGIN
  FOR T IN TABLES
  LOOP
    t_name := SUBSTR( REGEXP_REPLACE( T.TABLE_NAME, '[aeiou]', NULL, 1, 0, 'i' ), 1, 25 );
    EXECUTE IMMEDIATE 'CREATE SEQUENCE '||t_name||'_SEQ START WITH 1';
    EXECUTE IMMEDIATE 'UPDATE '||T.TABLE_NAME||' SET ID = '||t_name||'_SEQ.NEXTVAL';
    EXECUTE IMMEDIATE 'ALTER TABLE '||T.TABLE_NAME||' ADD CONSTRAINT '||t_name||'_UNQ PRIMARY KEY (ID)';
    EXECUTE IMMEDIATE 'CREATE OR REPLACE TRIGGER '||t_name||'_TRIG BEFORE INSERT ON '||T.TABLE_NAME||' FOR EACH ROW BEGIN :NEW.ID := '||t_name||'_SEQ.NEXTVAL; END;';
  END LOOP;
END;
/