MySQL update 語法


更新語法分 單表 和 多表

# 單表操作
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
    SET assignment_list
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

value:
    {expr | DEFAULT}

assignment:
    col_name = value

assignment_list:
    assignment [, assignment] ...


# 多表操作
UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET assignment_list
    [WHERE where_condition]


  • 1、update語句 更新匹配到的數據行中的部分或全部列的值。復值語句中的值可以是: 明確的值、表達式、關鍵字 DEFAULT (使用默認值)
  • 2、WHERE 從句給出過濾條件,確定要更新的行。如果沒有 條件where,則所有行都會被更新。
  • 3、如果有 ORDER BY 從句,則多個數據行按該順序更新
  • 4、LIMIT 限制更新條數
  • 5、多表操作沒有 order by 排序 和 limit 條數限制。
  • 6、每行只更新一次,即使多次配匹配
  • 7、table_references
table_references:
    escaped_table_reference [, escaped_table_reference] ...

escaped_table_reference: {
    table_reference
  | { OJ table_reference }
}

table_reference: {
    table_factor
  | joined_table
}

table_factor: {
    tbl_name [PARTITION (partition_names)]
        [[AS] alias] [index_hint_list]
  | [LATERAL] table_subquery [AS] alias [(col_list)]
  | ( table_references )
}

joined_table: {
    table_reference {[INNER | CROSS] JOIN | STRAIGHT_JOIN} table_factor [join_specification]
  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_specification
  | table_reference NATURAL [INNER | {LEFT|RIGHT} [OUTER]] JOIN table_factor
}

join_specification: {
    ON search_condition
  | USING (join_column_list)
}

join_column_list:
    column_name [, column_name] ...

index_hint_list:
    index_hint [, index_hint] ...

index_hint: {
    USE {INDEX|KEY}
      [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
  | {IGNORE|FORCE} {INDEX|KEY}
      [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
}

index_list:
    index_name [, index_name] ...
  • 8、where_condition 是一個表達式,可以使用MySQL支持的除聚合函數外的所有 函數 和 操作符
  • 9、修飾符:
    • 1)LOW_PRIORITY :將更新操作設為低優先級,在沒有其他客戶端讀取時,執行更新操作
    • 2)IGNORE : 會忽略一些錯誤,即使發生錯誤也不會停止語句的執行。唯一鍵的重復值錯誤也會忽略,但不會更新數據。
  • 10、 UPDATE IGNORE 語句 和包含 ORDER BY 從句的更新,對於基於語句的復制集時不安全的
  • 11、在表示式中 訪問將要更新的列,該列的值是其當前的值
# col1 最后的值是 在執行表示式時的當前值 + 1,即 原來的值 + 1
UPDATE t1 SET col1 = col1 + 1;

# col1 的值 同上, col2 的值 是 col1 的當前值,這時col1 已經 +1 了,所以 col2 最后和 col1 值相等
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
  • 12、單表更新的賦值一般是從左到右,而多表更新無法保證按照特定順序執行。
  • 13、如果將某一列 更新設置為其當前值(即新值和舊值相同),MySQL 不會更新這個列,不會多此一舉。
  • 14、在 SQL 嚴格模式下,將 NOT NULL 的列 更新為 NULL,會報錯。相反,在非嚴格模式下,會將值設置為其類型的隱式默認值,如,數字類型設置為 0,字符串設置為 空字符串 '',日期和時間類型設置為 ‘zero’
  • 15、給會自動生成值的列指定值,只能指定 DEFAULT。自動生成值的列,指的是在創建表時指定了計算表達式,通過其他列計算得到的列。
  • 16、UPDATE 語句會返回實際更新的行數。 mysql_info() C API 函數返回 在更新過程中匹配到的行數,更新了的行數,以及 警告數
  • 17、ORDER BY 的使用
# id 是唯一的數字列,若id有多個從小到大的連續值(1,2,3),此時更新會報錯。因為默認會按順序更新id:1+1 =》2 就會和已存在的 2 沖突
UPDATE t SET id = id + 1;

# 使用 order by id desc 按 id 倒序排列。先更新最大的值,就不會出新 重復值 錯誤
UPDATE t SET id = id + 1 ORDER BY id DESC;

  • 18、多表操作可以使用任何 在 SELECT 語句中的允許的 JOIN 從句,比如 內連接
# 在 table_references  中使用了 內連接
UPDATE  items,month SET items.price=month.price
WHERE items.id=month.id;
  • 19、如果多表更新時,包含有外鍵的InnoDB的表,則MySQL 優化器 可能不會按照父子關系的順序處理表,這樣的話,語句執行失敗,並回滾。
  • 20、不能更新一個和一個直接子查詢表相同的表。可以 將子查詢作為一個導出表, 再用多表更新的方式更新。
# 表結構
CREATE TABLE items (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    wholesale DECIMAL(6,2) NOT NULL DEFAULT 0.00,
    retail DECIMAL(6,2) NOT NULL DEFAULT 0.00,
    quantity BIGINT NOT NULL DEFAULT 0
);

# 更新 retail,直接子查詢,報錯
 UPDATE items
      SET retail = retail * 0.9
      WHERE id IN
          (SELECT id FROM items
              WHERE retail / wholesale >= 1.3 AND quantity > 100);
ERROR 1093 (HY000): You can't specify target table 'items' for update in FROM clause

# 將子查詢作為導出表(臨時表),再用多表更新的方式
UPDATE items,
       (SELECT id FROM items
        WHERE id IN
            (SELECT id FROM items
             WHERE retail / wholesale >= 1.3 AND quantity < 100))
        AS discounted
SET items.retail = items.retail * 0.9
WHERE items.id = discounted.id;

# 或者
UPDATE items,
       (SELECT id FROM items WHERE retail / wholesale >= 1.3 AND quantity < 100)
       AS discounted
    SET items.retail = items.retail * 0.9
    WHERE items.id = discounted.id;

# 或者
UPDATE items,
       (SELECT id, retail / wholesale AS markup, quantity FROM items)
       AS discounted
    SET items.retail = items.retail * 0.9
    WHERE discounted.markup >= 1.3
    AND discounted.quantity < 100
    AND items.id = discounted.id;

https://dev.mysql.com/doc/refman/8.0/en/update.html
表達式: https://dev.mysql.com/doc/refman/8.0/en/expressions.html
函數 和 操作符: https://dev.mysql.com/doc/refman/8.0/en/functions.html
自動生成列:https://dev.mysql.com/doc/refman/8.0/en/create-table-generated-columns.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM