1

我必须为很多表添加主键,并且我从 stackoverflow 获得了以下脚本(一个表):

ALTER TABLE table1 ADD ID NUMBER(12);
CREATE SEQUENCE table1Seq START WITH 1;
UPDATE table1 SET table1ID = table1Seq.NEXTVAL;
ALTER TABLE table1 ADD PRIMARY KEY (ID);
CREATE OR REPLACE TRIGGER table1PKSet
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
  :NEW.ID := table1Seq.NEXTVAL;
END;
/

但是现在我对用户的所有表都做了同样的操作。

所以我想知道我是否可以使用pl/sql来循环用户的所有表,并进行上述操作?

4

1 回答 1

5

在我开始之前,我只想说这很糟糕。如果您正在创建自动创建数据库的脚本,我会放弃下面的查询,只使用复制/粘贴,因为这太可怕了,它不属于您的数据库部署脚本。

查询

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 'ALTER TABLE '||T.TABLE_NAME||' ADD ID NUMBER(12)';
        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||'PKSet '||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;
/

这是做什么的?

基本上,它会获取一个表列表并动态构建 SQL 来完成所涉及的各种任务。EXECUTE IMMEDIATE获取我们构建 SQL 的字符串并执行它。讨厌的CHR(10)是换行符。我想要那里的空白,因为我不知道将其遗漏会如何影响 Oracle 的解析。请注意,在几个地方,我们将表名称直接连接到其他一些文本以生成序列或 PK 约束名称。

如果您在创建过程中引用了表名并且使用了一些小写字符,这可能会或可能不会出错。如果它确实出错,请记住每条语句都涉及一次提交。错误将意味着该过程已完成一半。如果架构不是当前用户,它也会失败。(您需要在 where 子句中更改USER_TABLESALL_TABLES添加适当的过滤器,并在构建 SQL 时在表名前面添加架构以使其在另一个架构上工作。)

一个实际工作的 SQLFiddle:http ://sqlfiddle.com/#!4/b67fc/ 1(我不敢相信这实际上在 SQLFiddle 上工作。)在这种情况下,我们感兴趣的查询在模式定义中结束,因为 SQL小提琴只允许SELECT在查询中。

祝你好运。你会需要它。不要朝自己的脚开枪。

于 2013-05-29T01:10:33.800 回答