Tôi đã gặp một số sự cố khi chèn dữ liệu hàng loạt từ một bảng khác vào bảng mới. Mục tiêu trông hơi như thế này:INSERT INTO/SELECT DISTINCT dẫn đến vi phạm khóa chính cho SYS_GUID
CREATE TABLE TEST_T (
T_GUID RAW(16) DEFAULT SYS_GUID() NOT NULL,
T_VAL1 NUMBER(10) NOT NULL,
T_VAL2 VARCHAR2(10) NOT NULL,
PRIMARY KEY (T_GUID)
)
các phiên bản đơn giản của bản tuyên bố tôi dự định để điền vào nó với dữ liệu:
INSERT INTO TEST_T (T_VAL1, T_VAL2)
SELECT DISTINCT
CAST(SUBSTR(zip_code, 1,1) AS NUMBER) as t_val1,
zip_code as t_val2
FROM OTHER_TABLE_T
WHERE ...
ORDER BY t_val1
Như tôi không cung cấp một T_GUID
có giá trị, tôi sẽ giả định đã tôi nhận được một cái được cung cấp bởi hàm SYS_GUID
cho mỗi dòng mới. Nhưng có điều gì đó sai, và tôi nhận được một sự vi phạm ràng buộc duy nhất cho khóa chính.
Nếu tôi xóa DISTINCT
, tuyên bố thành công, nhưng tôi nhận được nhiều mục nhập trùng lặp. Và, tất nhiên, nếu tôi cung cấp một cách rõ ràng một cuộc gọi SYS_GUID()
trong số SELECT
của tôi, có kết quả giống hệt nhau.
Bây giờ tôi thấy rằng nếu tôi chỉ cần đặt một SELECT
xung quanh tôi, nó hoạt động ra sao, không có hành vi vi phạm chế và các hàng riêng biệt được chèn vào:
INSERT INTO ...
SELECT x.* FROM (
SELECT DISTINCT ...
) x
Vì vậy, nơi nào các guids trùng lặp đến từ đâu? Nếu tập hợp đầy đủ các hàng không có vấn đề, tại sao sẽ xóa hàng thông qua sự cố gây ra khác biệt? Vì SYS_GUID tạo một mã định danh duy nhất cho mỗi cuộc gọi, tôi chỉ có thể tưởng tượng rằng trong trường hợp riêng biệt, nó chỉ được gọi một lần cho toàn bộ mệnh đề, được giải quyết bằng gói xung quanh SELECT
. Tôi sẽ rất hạnh phúc nếu có ai đó có thể giải thích cách thức thực hiện khác nhau trong trường hợp đó.
Bạn có chắc chắn guids là bản sao? Nhìn rất kỹ vào chúng, chúng trông giống nhau nhưng bạn nên chú ý ít nhất một nhân vật khác nhau trong mỗi chúng. – GriffeyDog
Mã của bạn có vẻ chính xác. Bạn có thể gặp lỗi Oracle, tra cứu "DUPLICATE SYS_GUID được tạo trên AIX có thể dẫn đến lỗi ORA-1 trong quá trình enqueue [ID 1371805.1]" trên Bộ phận Hỗ trợ Oracle của tôi. –