我在PL/SQL中合并两个表中的两列时遇到了巨大的困难。我从早上9点就开始做这个了,现在我放弃了,请帮帮我。
我想创建一个新表(称为temp)。它合并了来自两个不同表中其他两个列的信息。
Code So far
CREATE TABLE temp
(
temptimeKey CHAR(24) NOT NULL ,
temptimeHour INTEGER NULL ,
temptimeMinute INTEGER NULL ,
temptimeSecond INTEGER NULL ,
temptimeMonth INTEGER NULL ,
temptimeDay INTEGER NULL ,
temptimeYear INTEGER NULL ,
temptimeQuarter INTEGER NULL ,
CONSTRAINT XPKTEMPTIME PRIMARY KEY (temptimeKey)
);
insert into temp
SELECT
TO_CHAR(busFareDate, 'MM/DD/YYYY HH:MM:SS Q'),
TO_NUMBER(TO_CHAR(busFareDate, 'HH12')),
TO_NUMBER(TO_CHAR(busFareDate, 'MI')),
TO_NUMBER(TO_CHAR(busFareDate, 'SS')),
TO_NUMBER(TO_CHAR(busFareDate, 'MM')),
TO_NUMBER(TO_CHAR(busFareDate, 'DD')),
TO_NUMBER(TO_CHAR(busFareDate, 'YYYY')),
TO_NUMBER(TO_CHAR(busFareDate, 'Q'))
FROM
bus_fare
UNION
SELECT
TO_CHAR(trainFareDate, 'MM/DD/YYYY HH:MM:SS Q'),
TO_NUMBER(TO_CHAR(trainFareDate, 'HH12')),
TO_NUMBER(TO_CHAR(trainFareDate, 'MI')),
TO_NUMBER(TO_CHAR(trainFareDate, 'SS')),
TO_NUMBER(TO_CHAR(trainFareDate, 'MM')),
TO_NUMBER(TO_CHAR(trainFareDate, 'DD')),
TO_NUMBER(TO_CHAR(trainFareDate, 'YYYY')),
TO_NUMBER(TO_CHAR(trainFareDate, 'Q'))
FROM
train_fare;
drop table temp cascade constraints;
到目前为止,这段代码只违反了唯一约束:
ERROR at line 1:
ORA-00001: unique constraint (OPS$FNAVA.XPKTEMPTIME) violated
你能指出我做错了什么吗?(欢迎任何帮助)
试试这个:
insert into temp
SELECT
TO_CHAR(busFareDate, 'MM/DD/YYYY HH:MI:SS Q'),
TO_NUMBER(TO_CHAR(busFareDate, 'HH12')),
TO_NUMBER(TO_CHAR(busFareDate, 'MI')),
TO_NUMBER(TO_CHAR(busFareDate, 'SS')),
TO_NUMBER(TO_CHAR(busFareDate, 'MM')),
TO_NUMBER(TO_CHAR(busFareDate, 'DD')),
TO_NUMBER(TO_CHAR(busFareDate, 'YYYY')),
TO_NUMBER(TO_CHAR(busFareDate, 'Q'))
FROM (
SELECT busFareDate
FROM bus_fare
GROUP BY busFareDate
UNION
SELECT trainFareDate
FROM train_fare
GROUP BY trainFareDate) AS Dates
GROUP BY TO_CHAR(busFareDate, 'MM/DD/YYYY HH:MI:SS Q'),
TO_NUMBER(TO_CHAR(busFareDate, 'HH12')),
TO_NUMBER(TO_CHAR(busFareDate, 'MI')),
TO_NUMBER(TO_CHAR(busFareDate, 'SS')),
TO_NUMBER(TO_CHAR(busFareDate, 'MM')),
TO_NUMBER(TO_CHAR(busFareDate, 'DD')),
TO_NUMBER(TO_CHAR(busFareDate, 'YYYY')),
TO_NUMBER(TO_CHAR(busFareDate, 'Q'));
很奇怪,UNION应该自动删除重复项。这是在Oracle DBMS上吗?
UNIQUE约束违反错误是由于您的查询返回了您正在插入的表的键列的多行。
在您的示例中,TO_CHAR(trainFareDate, 'MM/DD/YYYY HH:MM:SS Q')将被插入键列。如果有两行具有相同的MM/DD/YYYY HH:MM:SS Q,您将得到此错误,假设您的DBMS真的在做"UNION ALL"。
你可以在主键上添加第二列,也许叫它"SOURCE",用"BUS"或"TRAIN"填充。
或者,您可以对表执行一个完整的外连接。
SELECT coalesce(busFareDate, trainFareDate) from
bus_fare FULL OUTER JOIN train_fare ON
(bus_fare.busFareDate = train_fare.trainFareDate);
然后使用该日期作为子查询执行所有需要在该日期执行的工作。
编辑:我认为你真正的问题可能来自于使用HH/HH12。
如果你这样做呢:
SELECT
TO_CHAR(fareDate , 'MM/DD/YYYY HH24:MI:SS Q'),
TO_NUMBER(TO_CHAR(fareDate , 'HH24')),
TO_NUMBER(TO_CHAR(fareDate , 'MI')),
TO_NUMBER(TO_CHAR(fareDate , 'SS')),
TO_NUMBER(TO_CHAR(fareDate , 'MM')),
TO_NUMBER(TO_CHAR(fareDate , 'DD')),
TO_NUMBER(TO_CHAR(fareDate , 'YYYY')),
TO_NUMBER(TO_CHAR(fareDate , 'Q'))
FROM
(SELECT coalesce(busFareDate, trainFareDate) fareDate from
bus_fare FULL OUTER JOIN train_fare ON
(bus_fare.busFareDate = train_fare.trainFareDate));
必须有违反约束的相同日期/时间的巴士票价和时间票价。为什么不尝试添加一个GUID列作为temp Table的主键,并使用newid()在联合的每一边生成值呢?
尝试在TO_CHAR()周围添加TRIM(),如:
TRIM(TO_CHAR(busFareDate, 'MM/DD/YYYY HH:MI:SS Q'))
我想我记得TO_CHAR有时会在你可能不期望的地方添加空格填充。如果空格填充导致总长度超过24个字符,那么当它进入临时表中的目标列时,它将被截断,这将使看起来存在重复,而实际上没有重复(即,它们仅在最后2或3个字符中不同,这些字符被截断)。
或者,将CHAR(24)列扩展为CHAR(1000)等更大的列,看看问题是否会消失。