Skip to main content
 首页 » 编程设计

Python:如何对文本文件中的 SQL 语句进行排序

2025年05月04日10xxx_UU

以下输出来自 Oracle;它使用提供的包生成“创建表”语句。我将它们输入到 python diff 工具 HtmlDiff 中,该工具在幕后使用 difflib。每个表后跟许多添加各种约束的“alter table add constraint”命令。

问题是“alter table”命令没有明确的顺序,我必须在生成输出文件后对它们重新排序,然后才能运行比较。 我需要帮助才能做到这一点;最好使用 python、sed 或 awk。

规则是 在包含“CREATE TABLE”的每一行之后直到包含“CREATE TABLE”的下一行 对包含“ADD CONSTRAINT”的每一行进行排序

这是我的输出示例:

    CREATE TABLE T1 
    (     BOOK_ID NUMBER NOT NULL ENABLE, 
      LOCATION_ID NUMBER NOT NULL ENABLE, 
             NAME VARCHAR2(255) NOT NULL ENABLE, 
     LEGAL_ENTITY VARCHAR2(255) NOT NULL ENABLE, 
           STATUS CHAR(1) NOT NULL ENABLE 
    ) ; 
 
ALTER TABLE T1 ADD CONSTRAINT T1_CHK_1 CHECK ( status IN ( 'A', 'I' , 'T' ) ) ENABLE; 
ALTER TABLE T1 ADD CONSTRAINT T1_PK PRIMARY KEY (BOOK_ID) ENABLE; 
ALTER TABLE T1 ADD CONSTRAINT T1_AK_1 UNIQUE (NAME) ENABLE; 
ALTER TABLE T1 ADD CONSTRAINT T1_FK_1 FOREIGN KEY (LOCATION_ID) REFERENCES T6 (LOCATION_ID) ENABLE; 
 
CREATE TABLE T2 
        (     
                    BUCKET_ID NUMBER  NOT NULL ENABLE, 
         DATA_LOAD_SESSION_ID NUMBER, 
                    IS_LOCKED CHAR(1) NOT NULL ENABLE, 
               LOCK_DATE_TIME DATE 
        ) ; 
ALTER TABLE T2 ADD CONSTRAINT CKC_IS_LOCKED_BUCKET CHECK (IS_LOCKED in ('T','F')) ENABLE; 
ALTER TABLE T2 ADD CONSTRAINT T2_PK PRIMARY KEY (BUCKET_ID) ENABLE; 
ALTER TABLE T2 ADD CONSTRAINT T2_FK_2 FOREIGN KEY (RRDB_STAGING_TABLE_ID) REFERENCES T4 (RRDB_STAGING_TABLE_ID) ENABLE; 
 
CREATE TABLE T3 
        (                   VALUE_DATE DATE, 
                               NODE_ID NUMBER, 
                            RESULT_UID VARCHAR2(255), 
         LATEST_EOD_SING_VAL_RESULT_ID NUMBER NOT NULL ENABLE 
        ) 
ALTER TABLE T3 ADD CONSTRAINT T3_PK PRIMARY KEY (VALUE_DATE, NODE_ID, RESULT_UID) ENABLE; 

期望的输出:唯一的区别是“ADD CONSTRAINT”行的顺序

CREATE TABLE T1 
    (     BOOK_ID NUMBER NOT NULL ENABLE, 
      LOCATION_ID NUMBER NOT NULL ENABLE, 
             NAME VARCHAR2(255) NOT NULL ENABLE, 
     LEGAL_ENTITY VARCHAR2(255) NOT NULL ENABLE, 
           STATUS CHAR(1) NOT NULL ENABLE 
    ) ; 
ALTER TABLE T1 ADD CONSTRAINT T1_AK_1 UNIQUE (NAME) ENABLE; 
ALTER TABLE T1 ADD CONSTRAINT T1_CHK_1 CHECK ( status IN ( 'A', 'I' , 'T' ) ) ENABLE; 
ALTER TABLE T1 ADD CONSTRAINT T1_FK_1 FOREIGN KEY (LOCATION_ID) REFERENCES T6 (LOCATION_ID) ENABLE; 
ALTER TABLE T1 ADD CONSTRAINT T1_PK PRIMARY KEY (BOOK_ID) ENABLE; 
 
CREATE TABLE T2 
    (     
                BUCKET_ID NUMBER  NOT NULL ENABLE, 
     DATA_LOAD_SESSION_ID NUMBER, 
                IS_LOCKED CHAR(1) NOT NULL ENABLE, 
           LOCK_DATE_TIME DATE 
    ) ; 
ALTER TABLE T2 ADD CONSTRAINT CKC_IS_LOCKED_BUCKET CHECK (IS_LOCKED in ('T','F')) ENABLE; 
ALTER TABLE T2 ADD CONSTRAINT T2_FK_2 FOREIGN KEY (RRDB_STAGING_TABLE_ID) REFERENCES T4 (RRDB_STAGING_TABLE_ID) ENABLE; 
ALTER TABLE T2 ADD CONSTRAINT T2_PK PRIMARY KEY (BUCKET_ID) ENABLE; 
 
CREATE TABLE T3 
    (                   VALUE_DATE DATE, 
                           NODE_ID NUMBER, 
                        RESULT_UID VARCHAR2(255), 
     LATEST_EOD_SING_VAL_RESULT_ID NUMBER NOT NULL ENABLE 
    ) 
ALTER TABLE T3 ADD CONSTRAINT T3_PK PRIMARY KEY (VALUE_DATE, NODE_ID, RESULT_UID) ENABLE; 

请您参考如下方法:

将其全部加载到一个字符串中,然后拆分为“;”构建一个 SQL 命令数组。循环数组并构建一个新的排序数组。传递 CREATE TABLE 位并将 ALTER TABLE 语句切出到一个单独的列表中。 sort() 更改列表并将其扩展到结果数组。完成后,';\n'.join(result_array) + ';'。