mysql cập nhật nhiều cột với cùng bây giờ ()


87

Tôi cần cập nhật 2 cột ngày giờ và tôi cần chúng hoàn toàn giống nhau, sử dụng mysql phiên bản 4.1.20. Tôi đang sử dụng truy vấn này:

mysql> update table set last_update=now(), last_monitor=now() where id=1;

Đó là an toàn hay có khả năng là các cột được cập nhật với thời gian khác nhau, vì 2 lệnh gọi hiển thị tới now()?
Tôi không nghĩ rằng nó có thể được cập nhật với các giá trị khác nhau (tôi nghĩ rằng nội bộ mysql gọi now()chỉ một lần trên mỗi hàng hoặc một cái gì đó tương tự), nhưng tôi không phải là chuyên gia, bạn nghĩ sao?

Cập nhật: Câu hỏi thứ hai đã được trích xuất tại đây .


1
Tôi khuyên bạn nên xóa câu hỏi thứ hai của mình khỏi đây, và cuối cùng đăng lại nó trong một bài đăng riêng biệt.
Cœur

Câu trả lời:


144

Đã tìm ra giải pháp:

mysql> UPDATE table SET last_update=now(), last_monitor=last_update WHERE id=1;

Tôi tìm thấy điều này trong MySQL Docs và sau một vài thử nghiệm, nó hoạt động:

câu lệnh sau đặt col2 thành giá trị col1 hiện tại (cập nhật), không phải giá trị col1 ban đầu. Kết quả là col1 và col2 có cùng giá trị. Hành vi này khác với SQL tiêu chuẩn.

CẬP NHẬT t1 SET col1 = col1 + 1, col2 = col1;


Có cách nào mà điều này không hoạt động không? Trong một thủ tục hoặc sử dụng phép nối với bảng tạm thời?
Soheil Rahsaz

7

Mysql không thông minh lắm. Khi bạn muốn sử dụng cùng một dấu thời gian trong nhiều truy vấn cập nhật hoặc chèn, bạn cần khai báo một biến.

Khi bạn sử dụng now()hàm, hệ thống sẽ gọi dấu thời gian hiện tại mỗi khi bạn gọi nó trong một truy vấn khác.


5

MySQL đánh giá now () một lần cho mỗi câu lệnh khi câu lệnh bắt đầu thực thi. Vì vậy, sẽ an toàn khi có nhiều lệnh gọi now () hiển thị trên mỗi câu lệnh.

select now(); select now(), sleep(10), now(); select now();
+---------------------+
| now()               |
+---------------------+
| 2018-11-05 16:54:00 |
+---------------------+
1 row in set (0.00 sec)

+---------------------+-----------+---------------------+
| now()               | sleep(10) | now()               |
+---------------------+-----------+---------------------+
| 2018-11-05 16:54:00 |         0 | 2018-11-05 16:54:00 |
+---------------------+-----------+---------------------+
1 row in set (10.00 sec)

+---------------------+
| now()               |
+---------------------+
| 2018-11-05 16:54:10 |
+---------------------+
1 row in set (0.00 sec)

1

Bạn có thể lưu trữ giá trị của now () trong một biến trước khi chạy truy vấn cập nhật và sau đó sử dụng biến đó để cập nhật cả các trường last_updatelast_monitor.

Điều này sẽ đảm bảo now () chỉ được thực thi một lần và cùng một giá trị được cập nhật trên cả hai cột mà bạn cần.


1

Bạn có thể đặt mã sau vào giá trị mặc định của cột dấu thời gian:, CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPvì vậy khi cập nhật, hai cột có cùng giá trị.


1
AFAIK "khi cập nhật" có giới hạn một cột trên mỗi bảng, vì vậy không thể đặt nó thành cả hai cột.
Radu Maris

0

Nếu bạn thực sự cần chắc chắn rằng now()có cùng giá trị, bạn có thể chạy hai truy vấn (điều đó cũng sẽ trả lời cho câu hỏi thứ hai của bạn, trong trường hợp đó bạn đang yêu cầu update last_monitor = to last_updatenhưng last_updatechưa được cập nhật)

bạn có thể làm điều gì đó như:

mysql> update table set last_update=now() where id=1;
mysql> update table set last_monitor = last_update where id=1;

Dù sao thì tôi nghĩ rằng mysql đủ thông minh để chỉ yêu cầu now()một lần cho mỗi truy vấn.


Làm thế nào về hai bản cập nhật? bạn cũng đoán mysql có đủ thông minh để kết hợp chúng thành một câu lệnh không? bởi vì nó sẽ không.
Rafael Herscovici

0

Có 2 cách để làm điều này;

Đầu tiên , tôi khuyên bạn nên khai báo now () dưới dạng một biến trước khi đưa nó vào câu lệnh sql. Hãy cùng nói nào;

var x = now();
mysql> UPDATE table SET last_update=$x, last_monitor=$x WHERE id=1;

Về mặt logic, nếu bạn muốn một đầu vào khác cho last_monitor thì bạn sẽ thêm một biến khác như;

var y = time();
mysql> UPDATE table SET last_update=$x, last_monitor=$y WHERE id=1;

Bằng cách này, bạn có thể sử dụng các biến nhiều lần nhất có thể, không chỉ trong các câu lệnh mysql mà còn trong ngôn ngữ kịch bản phía máy chủ (như PHP) mà bạn đang sử dụng trong dự án của mình. Hãy nhớ rằng các biến tương tự này có thể được chèn làm đầu vào trong một biểu mẫu trên giao diện người dùng của ứng dụng. Điều đó làm cho dự án động chứ không phải tĩnh.

Thứ hai, nếu now () cho biết thời gian cập nhật thì bằng cách sử dụng mysql, bạn có thể dán thuộc tính của hàng làm dấu thời gian. Mỗi khi một hàng được chèn hoặc thời gian cập nhật cũng được cập nhật.


Chào mừng đến với SO. Mặc dù đây là một giải pháp cho vấn đề, nhưng nó không thực sự trả lời câu hỏi là "Có vấn đề khi sử dụng hàm NOW () tích hợp sẵn mysql không?". Ngoài ra, bạn đề xuất sử dụng ngôn ngữ bên ngoài mà người đăng có thể không kiểm soát được. Đề xuất thứ 2 của bạn Tôi không chắc lắm (hồi ức của tôi về mysql không chi tiết lắm) nhưng việc hỗ trợ nó bằng các liên kết đến một số tài liệu / ví dụ sẽ mang lại uy tín hơn nhiều.
Martin

Trong gợi ý thứ hai của tôi, nếu bây giờ () được sử dụng làm dấu thời gian bất cứ khi nào diễn ra bất kỳ cập nhật nào, liên kết sau có thể giúp ích cho bạn; alvinalexander.com/mysql/… Trong gợi ý đầu tiên của tôi, mỗi cột trong bảng mysql là độc lập. Do đó, việc nhập dữ liệu (như sử dụng một biến trong câu hỏi ở trên) được thực hiện độc lập. Tuy nhiên, bạn có thể so sánh và đối chiếu dữ liệu trong các cột khác nhau bằng các toán tử như>, <, =,! =,! <. Điều này đơn giản có nghĩa là bạn không thể nhập dữ liệu vào các cols như thế này; mysql> cập nhật bảng đặt last_update = last_monitor = now () where id = 1;
Wahinya Brian
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.