Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 参考 » 使用 SQL » SQL 语句 » SQL 语句 (P-Z)

 

UPDATE 语句

此语句用于修改数据库表中的现有行。

语法 1
UPDATE [ row-limitation ] table-list ] 
SET set-item, ...
[ FROM table-expression [,...] ]
[ WHERE search-condition ]
[ ORDER BY expression [ ASC | DESC ] , ... ]
[ OPTION( query-hint, ... ) ]
table-list : 
table-name [,...]  
table-name : 
[ owner.]table-name [ [ AS ] correlation-name ]
| [ owner.]view-name [ [ AS ] correlation-name ]
| derived-table
derived-table : 
( select-statement ) 
[ AS ] correlation-name [ ( column-name [,... ] ) ]
table-expression: 
完整的表表达式可包含连接。请参见FROM 子句
语法 2
UPDATE table-name
SET set-item, ...
VERIFY ( column-name, ... ) VALUES ( expression, ... ) 
[ WHERE search-condition ]
[ ORDER BY expression [ ASC | DESC ], ... ]
[ OPTION( query-hint, ... ) ]
语法 3
UPDATE [ owner.]table-name
PUBLICATION publication
{  SUBSCRIBE BY expression
| OLD SUBSCRIBE BY expression NEW SUBSCRIBE BY expression
    }
WHERE search-condition
row-limitation :
  FIRST 
| TOP n [ START AT m ]
set-item :
[ correlation-name.]column-name = { expression | DEFAULT }
| [owner-name.]table-name.column-name = { expression | DEFAULT }
| @variable-name = expression
query-hint :
MATERIALIZED VIEW OPTIMIZATION option-value
| FORCE OPTIMIZATION
| FORCE NO OPTIMIZATION
| option-name = option-value
table-name : 
[ owner.]base-table-name
| temporary-table-name
| derived-table-name
| [ owner.]view-name
option-name : identifier
option-value : hostvar (indicator allowed), string, identifier, or number
参数
  • UPDATE 子句   对于语法 1,table-list 可包括临时表、派生表或视图。可对视图和派生表进行更新,除非它们是不可更新的。对于语法 2 和语法 3,table-name 必须为基表。

    仅当定义视图的查询说明为可更新时,才能对视图执行 UPDATE 语句。有关识别固有不可更新的视图的详细信息,请参见使用视图

  • row-limitation 子句   行限制子句允许您只返回满足 WHERE 子句的行的子集。TOP 和 START AT 值可以是主机变量、整型常量或整型变量。TOP 值必须大于等于 0。START AT 值必须大于 0。通常,在指定这些子句时也指定 ORDER BY 子句,这样可以用一种有意义的方式对这些行进行排序。请参见显式限制查询返回的行数

  • SET 子句   set 子句指定列,并指定如何更改值。

    可通过下列格式使用 SET 子句将列设置为计算列值:

    SET column-name = expression, ...

    每个指定的列被设置为等号右侧表达式的值。对表达式没有任何限制。如果表达式为 column-name,则使用旧值。

    如果某列定义了缺省值,则可以使用 SET 子句将该列设置为其缺省值。有关这一用法的示例,请参见示例部分。

    还可以通过下列格式使用 SET 子句为变量赋值:

    SET @variable-name = expression, ...

    为变量赋值时,变量必须已经声明,而且变量名必须以 "at" 符号 (@) 开头。变量和列赋值可以混合在一起,并且可以使用任意数字。如果 SET 列表中赋值号左边的名称不仅与变量名匹配,还与更新表中的某列匹配,此语句将更新该列。

    以下是部分 UPDATE 语句的示例。它不仅更新表,还为变量赋值:

    UPDATE T SET @var = expression1, col1 = expression2
    WHERE...

    这等效于:

    SELECT @var = expression1
    FROM T
    WHERE... ;
    UPDATE T SET col1 = expression2
    WHERE...

  • FROM 子句   如果存在 FROM 子句,WHERE 子句将限定 FROM 子句的行。

    FROM table-expression 子句允许根据连接来更新表。table-expression 可以包含任意复杂表的表达式,如 KEY 和 NATURAL 连接。有关 FROM 子句和连接的完整说明,请参见FROM 子句

    如果使用 FROM 子句,在语句的两个部分必须以同样的方式限定表名。如果在一个位置使用了相关名,则在另一个位置也必须使用该相关名,否则将发生错误。

    下面的语句阐释 UPDATE 语句(有两个使用相关名的 FROM 子句)的表名中潜在的不明确性:
    UPDATE
    FROM table_1
    FROM table_1 AS alias_1, table_2 AS alias_2
    WHERE ...

    表 table_1 在第一个 FROM 子句中没有相关名标识,而在第二个 FROM 子句中具有相关名标识。在本例中,第一个子句中的 table_1 在第二个子句中用 alias_1 标识—此语句中只有一个 table_1 实例。这是一般规则的特例,即同一语句中,一个表一次用相关名标识另一次没有相关名,则将视为出现表的两个实例。

    但以下示例中,第二个 FROM 子句中有两个 table_1 的实例。此语句因语法错误而失败,因为不明确第二个 FROM 子句中的哪个 table_1 实例与第一个 FROM 子句中的第一个 table_1 实例匹配。

    UPDATE
    FROM table_1
    FROM table_1 AS alias_1, table_1 AS alias_2
    WHERE ...

    仅当 ansi_update_constraints 设置为 Off 时,才能使用此子句。请参见ansi_update_constraints 选项 [兼容性]

    有关连接的完整说明,请参见连接:从多个表检索数据

    有关详细信息,请参见FROM 子句

  • WHERE 子句   如果指定 WHERE 子句,则只更新满足搜索条件的行。如果未指定 WHERE 子句,则更新所有行。

  • ORDER BY 子句   通常情况下,行以什么顺序更新并不重要。但与 FIRST 或 TOP 子句联用时,顺序就非常重要。

    不能在 ORDER BY 子句中使用列序号。

    除非将 ansi_update_constraints 选项设置为 Off,否则不得更新 ORDER BY 子句中出现的列。请参见ansi_update_constraints 选项 [兼容性]

  • OPTION 子句   此子句用于指定执行语句时的提示。支持以下提示:

    • MATERIALIZED VIEW OPTIMIZATION option-value
    • FORCE OPTIMIZATION
    • FORCE NO OPTIMIZATION
    • option-name = option-value

注释

插入到表中的字符串始终以它们输入时采用的大小写进行保存,而不论数据库是否区分大小写。用字符串 Street 更新的 CHAR 数据类型列在数据库中保存的形式始终是 S 为大写,其它字母均为小写。SELECT 语句返回的字符串为 Street。但是,如果数据库不区分大小写,所有比较都会将 Street 与 street、STREET 等不同大小写形式的字符串视为相同。而且,如果单列主键已经包含 Street 条目,则会拒绝对 street 执行 INSERT 操作,因为它会导致主键不唯一。

如果新值与旧值没有差别,则不更改数据。但是,每次行上发生 UPDATE(更新)时,无论新值是否与旧值相同,都触发 BEFORE UPDATE 触发器。AFTER UPDATE 触发器只在新值与旧值不同时才触发。

UPDATE 语句的语法 1 修改一个或多个表中的行值。语法 2 和语法 3 仅适用于 SQL Remote。

语法 2 仅用于 SQL Remote 中由消息代理执行单个表的单行更新。VERIFY 子句包含在要更新的行中应存在的值集。如果值不匹配,则继续 UPDATE 操作之前会触发所有 RESOLVE UPDATE 触发器。如果只是 VERIFY 子句不匹配,UPDATE 不会失败。

UPDATE 语句的语法 3 用于实现特定的 SQL Remote 功能,并且在 BEFORE 触发器内使用。每当列表更改时,它都提供 SUBSCRIBE BY 值的完整列表。它放在 SQL Remote 触发器中,以便数据库服务器能够计算 SUBSCRIBE BY 值的当前列表。这两个列表都放置在事务日志中。

消息代理使用这两个列表来确保将行移动到任何没有行且现在需要行的远程数据库。消息代理还从任何含有行且不再需要行的远程数据库中删除行。UPDATE 语句不影响含有行且仍然需要行的远程数据库。

对于在 SUBSCRIBE BY 子句中用子查询创建的发布,必须编写包含 UPDATE 语句的语法 3 的触发器,以确保各行保留在它们正确的预订中。

UPDATE 语句的语法 3 允许显式指定旧 SUBSCRIBE BY 列表和新 SUBSCRIBE BY 列表,从而使 SQL Remote 触发器的效率更高。如果缺少这些列表,数据库服务器将计算发布定义中的旧 SUBSCRIBE BY 列表。由于新 SUBSCRIBE BY 列表与旧 SUBSCRIBE BY 列表通常只是稍微有点差别,因此可能会执行两次旧列表的计算。通过既指定旧列表又指定新列表,可以避免这种额外的工作。

SUBSCRIBE BY 表达式是一个值或一个子查询。

UPDATE 语句的语法 3 在事务日志中创建项,但不更改数据库表。

使用 UPDATE 语句更新大量数据时,也会更新列的统计信息。

权限

必须具有所修改列的 UPDATE 权限。

副作用

更新列统计信息。

另请参见
标准和兼容性
  • SQL/2003   除 FROM 和 ORDER BY 子句是服务商扩充外,语法 1 是核心特性。语法 2 和语法 3 是仅用于 SQL Remote 的服务商扩充。

    要强制实现与 SQL/2003 的兼容,请确保将 ansi_update_constraints 选项设置为 Strict。请参见ansi_update_constraints 选项 [兼容性]

示例

此示例使用示例数据库将雇员 Philip Chin(雇员 129)从销售部转移到市场部。

UPDATE Employees
SET DepartmentID = 400
WHERE EmployeeID = 129;

利用示例数据库,以下示例通过从 ID 中减去 2000 来对所有现有销售订单重新编号。

UPDATE SalesOrders AS orders
SET orders.ID = orders.ID - 2000
ORDER BY orders.ID ASC;

仅当使用 ON UPDATE CASCADE 操作定义 SalesOrderItems 表(引用主键 SalesOrders.ID 的表)的外键时,才可能进行此更新。SalesOrderItems 表同样也会更新。

有关外键属性的详细信息,请参见ALTER TABLE 语句CREATE TABLE 语句

此示例使用示例数据库,以隔离级别 2 而不是以数据库的当前隔离级别设置更改产品的价格。

UPDATE Products
SET UnitPrice = 7.00
WHERE ID = 501
OPTION( isolation_level = 2 );

以下示例显示如何更新表以将某列设置为其缺省值。以下示例将创建一个表 MyTable,用数据填充该表,然后执行 UPDATE 语句,指定 SET 子句将列值更改为其缺省值。

CREATE TABLE MyTable(
   PK INT PRIMARY KEY  DEFAULT AUTOINCREMENT,
   TableName CHAR(128) NOT NULL,
   TableNameLen INT DEFAULT 20,
   LastUser CHAR(10) DEFAULT last user,
   LastTime TIMESTAMP DEFAULT TIMESTAMP,
   LastTimestamp TIMESTAMP DEFAULT @@dbts );

INSERT INTO MyTable WITH AUTO NAME
   SELECT
      LENGTH(t.table_name) AS TableNameLen,
      t.table_name AS TableName
   FROM SYS.SYSTAB t
   WHERE table_id<=10;

UPDATE MyTable SET  LastTime = DEFAULT, LastTimestamp = DEFAULT
   WHERE TableName LIKE '%sys%';