2008-11-13 48 views
17

Có thể chèn một hàng không, nhưng chỉ khi một trong các giá trị đã có trong bảng không tồn tại?Có thể chèn một hàng nhưng chỉ khi một giá trị chưa tồn tại?

Tôi đang tạo Giới thiệu với bạn bè với các điểm giới thiệu cho hệ thống thương mại điện tử, nơi tôi cần chèn email của người bạn vào bảng cơ sở dữ liệu, nhưng chỉ khi nó chưa có trong bảng. Điều này là do tôi không muốn nhiều hơn 1 người nhận được điểm giới thiệu khi khách hàng mới đăng ký và mua một thứ gì đó. Vì vậy, tôi chỉ muốn một email một lần trong bảng.

Tôi đang sử dụng PHP 4 và MySql 4.1.

Trả lời

21

Nếu cột là một khóa chính hoặc một chỉ số duy nhất:

INSERT INTO table (email) VALUES (email_address) ON DUPLICATE KEY UPDATE 
email=email_address 

Biết may mắn của tôi có một cách tốt hơn để làm việc đó mặc dù. AFAIK không có tương đương với "ON KHÓA KHÓA KHÔNG" trong MySQL. Tôi không chắc chắn về email = email_Address bit, bạn có thể chơi và xem nó có hoạt động không mà bạn phải chỉ định một hành động. Như ai đó nói ở trên, mặc dù, nếu nó có những ràng buộc duy nhất trên nó thì không có gì sẽ xảy ra. Và nếu bạn muốn tất cả các địa chỉ email trong một bảng là duy nhất thì không có lý do nào để chỉ định nó là duy nhất trong định nghĩa cột của bạn.

+0

Tôi đặt email thành một khóa duy nhất trong phpMyAdmin rồi sử dụng mã của bạn. Và nó hoạt động rất tốt! Cảm ơn bạn – alex

+0

Re: không tương đương với ON KHÓA KHÓA KHÔNG LÀM. Xem giải pháp của Todd. Ngoài ra, bạn có thể có thể làm một cái gì đó giống như ON DUPLICATE KEY UPDATE email = email, mặc dù nó chắc chắn lãng phí hơn. –

1

Tôi không chắc chắn nếu tôi đã nhận nó, nhưng những gì về một

try { 
    mysql_query($sql); 
} 
catch(Exception $e) { 

} 

kết hợp với một số lĩnh vực duy nhất trong MySQL?

nếu nó ném ngoại lệ thì bạn biết rằng bạn có trường trùng lặp. Xin lỗi nếu điều đó không trả lời câu hỏi của bạn ..

+0

Cảm ơn phản hồi của bạn, nhưng tôi không nghĩ rằng nó giải quyết vấn đề của tôi. Tôi muốn một truy vấn duy nhất chèn hàng hoặc không làm gì nếu nó không thành công. – alex

+0

Nếu một ngoại lệ được ném, thì hàng sẽ không được thêm vào. Bạn chỉ có thể đăng nhập, hoặc không phải làm gì trong phần đánh bắt. – Feet

+0

Nhưng với truy vấn trước đó, nó gây ra lỗi mỗi lần. Tôi muốn nó thất bại trong mySql. – alex

0

Nếu trường email là khóa chính thì các ràng buộc trên bảng sẽ ngăn không cho nhập trùng lặp.

6

Nhiều khả năng một cái gì đó như:

IF NOT EXISTS(SELECT * FROM myTable WHERE [email protected]) THEN INSERT INTO blah blah 

Điều đó có thể được cuộn thành một truy vấn cơ sở dữ liệu.

32

này hoạt động nếu bạn có một chỉ số duy nhất hoặc khóa chính trên cột (EmailAddr trong ví dụ này):

INSERT IGNORE INTO Table (EmailAddr) VALUES ('[email protected]') 

Sử dụng này nếu một kỷ lục với email đó đã tồn tại (sao chép vi phạm key) thay vì một lỗi, câu lệnh vừa thất bại và không có gì được chèn vào.

Xem MySql docs để biết thêm thông tin.

+0

"INSERT IGNORE" là câu trả lời hay nhất, nhưng REPLACE (http://dev.mysql.com/doc/refman/5.0/en/replace.html) cũng là một tùy chọn nếu bạn muốn chèn lại hàng vì một lý do nào đó (có thể là một dấu thời gian hoặc một cái gì đó). – gpojd

+4

Hãy cảnh giác với REPLACE tăng tự động của bạn - dưới mui xe nó chỉ là một DELETE, INSERT. –

+0

hoạt động tốt cho tôi, phải có chỉ mục duy nhất – Gordon

0

MySQL cung cấp REPLACE INTO http://dev.mysql.com/doc/refman/5.0/en/replace.html:

REPLACE tác phẩm giống hệt như INSERT, trừ rằng nếu một hàng cũ trong bảng có giá trị tương tự như một hàng mới cho một PRIMARY KEY hoặc một chỉ số duy nhất, hàng cũ bị xóa trước khi hàng mới được chèn vào.

3

Một sửa đổi chút ít/Ngoài câu trả lời naeblis của:

INSERT INTO table (email) VALUES (email_address) 
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id) 

Bằng cách này bạn không cần phải ném email=email_address trong đó bạn nhận được giá trị chính xác cho LAST_INSERT_ID() nếu các bản cập nhật trình bày.

Nguồn: MySQL Documents: 12.2.5.3

Các vấn đề liên quan