我希望我的 Oracle 行按照我的复合主键(WORK_DATE、EMP_ID)的确切升序排序。在 SQL Server 中,创建聚集索引可以轻松神奇地解决问题。乍一看,Oracle 的 ORGANIZATION INDEX(或 IOT)似乎提供了一个可行的解决方案,但事实并非如此。
以下 DDL 说明了该问题。我已经使数据尽可能真实,特别是我有一个相当大的 VARCHAR 字段,该字段的大小因行而异(这可能会阻止 Oracle 重新排序行的存储)。
我正在寻找一种解决方案,该解决方案可以使行以查询#2 的输出的方式存储,而临时用户不必添加“ORDER BY 1, 2”。我有笨拙的用户忘记添加 ORDER BY 语句,他们CTRL+END到底部,认为他们正在获取最新的 WORK_DATE。我不想通过创建一个包含嵌入式 ORDER BY 语句的视图来解决这个问题。您能否建议对 DDL 声明进行更正?也许我需要在“ORGANIZATION INDEX”关键字之后添加额外的子句或参数?谢谢你的帮助。
CREATE TABLE EMPLOYEE_HOURS (
WORK_DATE DATE NOT NULL
, EMP_ID VARCHAR2(15) NOT NULL
, HOURS_WORKED NUMBER(22) NOT NULL
, WORK_COMMENT VARCHAR2(150) NOT NULL
, ROW_INSERT_DATE TIMESTAMP DEFAULT SYSTIMESTAMP
, CONSTRAINT EMPLOYEE_HOURS_PK PRIMARY KEY (WORK_DATE, EMP_ID)
) ORGANIZATION INDEX;
/* create test data that mimics my real world data */
BEGIN
FOR loop_id IN 1 .. 10000
LOOP
INSERT INTO EMPLOYEE_HOURS VALUES (
TRUNC(SYSDATE) - TRUNC(dbms_random.value(-150, 150))
, UPPER(dbms_random.string('A', 3))
|| TRUNC(dbms_random.value(1000, 999999))
, dbms_random.value(0.5, 18.5)
, regexp_replace(SUBSTR(LOWER(dbms_random.string('A', 100))
, 1
, TRUNC(dbms_random.value(4, 100))), '(.....)', '\1 ')
, SYSTIMESTAMP);
COMMIT WORK;
END LOOP;
END;
/* compare these queries and notice that the sort order in the first query does not
conform to the expected order of the IOT composite index (WORK_DATE, EMP_ID) */
/* Query #1 */
SELECT * FROM EMPLOYEE_HOURS;
/* Query #2 */
SELECT * FROM EMPLOYEE_HOURS ORDER BY 1, 2;