2009-07-17 33 views
60

Ngắn câu chuyện, tôi có tệp SQL mà tôi muốn nhập dưới dạng tệp kiểu skel, vì vậy việc này sẽ được thực hiện nhiều lần, theo lập trình. Tôi có thể chỉnh sửa các tập tin SQL tuy nhiên tôi muốn, nhưng tôi không muốn chạm vào ứng dụng riêng của mình.Cách buộc MySQL lấy 0 làm giá trị gia tăng tự động hợp lệ

Ứng dụng này sử dụng userid = 0 để đại diện cho người dùng ẩn danh. Nó cũng có một mục có liên quan (trống) trong cơ sở dữ liệu để đại diện cho 'người dùng' này. Do đó, các dòng trong skel.sql của tôi trông giống như sau:

INSERT INTO `{{TABLE_PREFIX}}users` VALUES (0, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL); 

Vấn đề với điều này là uid là một lĩnh vực auto_increment, mà, về mặt kỹ thuật, 0 là một giá trị không hợp lệ. Hoặc ít nhất, nếu bạn đặt nó là 0, về cơ bản bạn đang nói với MySQL, "Hãy chèn id tiếp theo vào trường này."

Bây giờ, tôi giả sử tôi có thể đặt INSERT rồi truy vấn UPDATE vào tệp SQL của mình, nhưng có cách nào nói cho MySQL nói chung là có, tôi thực sự muốn chèn 0 vào trường này?

Trả lời

74

Từ câu trả lời tôi nhận được here:

Bạn có thể sử dụng:

SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO' 

nào như mô tả here, sẽ ngăn chặn MySQL từ giải thích một ID INSERT/UPDATE từ 0 như là chuỗi tiếp theo ID. Hành vi như vậy sẽ được giới hạn trong NULL.

Đó là những gì tôi xem là hành vi khá xấu từ ứng dụng. Bạn sẽ phải thật cẩn thận rằng nó được sử dụng nhất quán, đặc biệt nếu bạn chọn triển khai sao chép vào một ngày sau đó.

+12

Một điều bạn phải cẩn thận: 'sql_mode' là danh sách cờ được phân cách bằng dấu phẩy. Nếu bạn làm 'sql_mode = 'NO_AUTO_VALUE_ON_ZERO'', bạn có thể vô tình vô hiệu hóa các cờ khác – Kip

+0

Giải pháp này về cơ bản đã làm việc cho tôi, tuy nhiên kết xuất của tôi cũng bao gồm một số nơi nó ghi đè' sql_mode' ở giữa tệp sql và sau đó đặt lại biến 'OLD_SQL_MODE' đã được đặt để hoàn nguyên về cuối tập lệnh. Điều này đã ghi đè 'NO_AUTO_VALUE_ON_ZERO' của tôi ở giữa tập lệnh của tôi khiến việc này không hoạt động. Giải pháp của tôi là tạo một biến mới của 'INIT_OLD_SQL_MODE' mà tôi đã sử dụng để đặt lại ở cuối và sau khi tôi đặt' sql_mode' thành 'NO_AUTO_VALUE_ON_ZERO', tôi đặt một biến mới' OLD_SQL_MODE' mà những ghi đè tạm thời đó có thể đặt lại thành –

19

Kiểm tra chế độ DB sql của bạn với:

SELECT @@[GLOBAL|SESSION].sql_mode; 

Nếu đó là rỗng hoặc không được thiết lập, sử dụng:

SET [GLOBAL|SESSION] sql_mode='NO_AUTO_VALUE_ON_ZERO' 

hãy cẩn thận! Nếu bạn sử dụng GLOBAL, đó không phải là thay đổi ngay lập tức, bạn cần phải khởi động lại kết nối của mình để áp dụng cài đặt. Vì vậy, nếu bạn đang khôi phục dữ liệu từ một DB khác, và bạn không chắc chắn cài đặt này có được áp dụng hay không, hãy sử dụng SESSION để thay đổi ngay lập tức (cài đặt này sẽ đặt lại khi đóng kết nối). Khi hoàn thành, chèn 0 giá trị và nó sẽ không thay đổi ngay cả khi sql_mode bị thay đổi.

Để thiết lập lại chế độ này (và những người khác) sử dụng

SET [GLOBAL|SESSION] sql_mode='' 

Zero, giá trị auto-increment không được khuyến khích vì họ đang không được đặt làm mặc định trong cơ sở dữ liệu MySQL.

Để biết thêm thông tin kiểm tra mysql dev page topic về vấn đề này

5

thất bại cách an toàn:

SET @@session.sql_mode = 
    CASE WHEN @@session.sql_mode NOT LIKE '%NO_AUTO_VALUE_ON_ZERO%' 
     THEN CASE WHEN LENGTH(@@session.sql_mode)>0 
      THEN CONCAT_WS(',',@@session.sql_mode,'NO_AUTO_VALUE_ON_ZERO') -- added, wasn't empty 
      ELSE 'NO_AUTO_VALUE_ON_ZERO'         -- replaced, was empty 
     END 
     ELSE @@session.sql_mode            -- unchanged, already had NO_AUTO_VALUE_ON_ZERO set 
    END 
  • Kiểm tra nếu NO_AUTO_VALUE_ON_ZERO đã được thiết lập trong sql_mode
  • Thêm để sql_mode nếu không có sản phẩm nào
  • Sets chỉ phiên, tôi khuyên bạn chỉ nên sử dụng nó trong các phiên mà bạn cần phải chèn 0
4

Nếu bạn không muốn mangle với các biến mysql, đây là một hack hữu ích:

INSERT INTO `{{TABLE_PREFIX}}users` VALUES (-1, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, 0, NULL, '', '', '', NULL); 

Và sau đó

UPDATE `{{TABLE_PREFIX}}users` SET id = 0 where id = -1; 

Rõ ràng, điều này giả định rằng bạn không sử dụng các giá trị âm cho id bảng của bạn.

+6

Rõ ràng , nó không hoạt động nếu bạn đang sử dụng một số nguyên không dấu. – fnkr

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