为指定表中的指定列设置新值。
大纲UPDATE [%keyword] table-ref [[AS] t-alias]
value-assignment-statement
[FROM [optimize-option] select-table [[AS] t-alias]
{, select-table2 [[AS] t-alias]} ]
[WHERE condition-expression]
UPDATE [%keyword] table-ref [[AS] t-alias]
value-assignment-statement
[WHERE CURRENT OF cursor]
value-assignment-statement ::=
SET column1 = scalar-expression1 {,column2 = scalar-expression2} ... |
[ (column1 {,column2} ...) ] VALUES (scalar-expression1 {,scalar-expression2} ...) |
VALUES :array()
参数
-
%keyword
- 可选参数:%NOCHECK
, %NOFPLAN
, %NOINDEX
, %NOJOURN
, %NOLOCK
, %NOTRIGGER
, %PROFILE
, %PROFILE_ALL
。 -
table-ref
- 要更新数据的现有表的名称。
还可以指定一个视图,通过该视图对表执行更新。
不能在此参数中指定表值函数或JOIN
语法。表名(或视图名)可以是限定的(
schema.table
)或非限定的(table
)。
使用模式搜索路径(如果提供的话)或默认模式名将非限定名称匹配到其模式。
-
AS t-alias
- 可选- table-ref
(表或视图)名称的别名。
别名必须是有效的标识符。 AS关键字是可选的。
-
FROM select-table
- 可选的——FROM子句,用于指定用于确定要更新哪些行的表。
多个表可以指定为逗号分隔的列表或与ANSI连接关键字关联。
可以指定任何表或视图的组合。
如果在这里在两个选择表之间指定逗号, IRIS将对表执行CROSS JOIN
,并从JOIN
操作的结果表中检索数据。如果在这里指定两个选择表之间的
ANSI
连接关键字, IRIS将执行指定的连接操作。可以选择指定一个或多个优化选项关键字来优化查询执行。
可用的选项有:
%ALLINDEX
、%FIRSTTABLE select-table
、%FULL
、%INORDER
、%IGNOREINDICES
、%NOFLATTEN
、%NOMERGE
、%NOSVSO
、%NOTOPOPT
、% nounoropt
、%PARALLEL
、%STARTTABLE
。
-
WHERE condition-expression
- 可选-指定一个或多个布尔谓词,用于确定要更新哪些行。
如果没有提供WHERE
子句(或WHERE CURRENT OF
子句),UPDATE
将更新表中的所有行。
-
WHERE CURRENT OF cursor
- 可选:仅嵌入SQL—指定UPDATE
操作更新游标当前位置的记录。
可以指定WHERE CURRENT OF
子句或WHERE
子句,但不能同时指定两者。
-
column
- 可选—现有列的名称。
多个列名指定为逗号分隔的列表。 如果省略,则更新所有列。
-
scalar-expression
- 用标量表达式表示的列数据值。
多个数据值指定为逗号分隔的列表,其中每个数据值依次对应于一个列。
-
:array()
- 仅嵌入式SQL—指定为主机变量的值数组。
数组的最低下标级别必须是未指定的。
因此::myupdates()
, :myupdates(5,)
和 :myupdates(1,1,)
都是有效的规范。
UPDATE
命令更改表中列的现有值。可以直接更新表中的数据,也可以通过视图进行更新,或者使用括在括号中的子查询进行更新。
通过视图进行更新受制于需求和限制,如
CREATE view
中所述。
UPDATE
命令为包含这些列的一个或多个现有基表行提供一个或多个新列值。将数据值赋给列是使用值赋值语句完成的。
默认情况下,值赋值语句更新表中的所有行。
更常见的是,
UPDATE
根据条件表达式指定对特定的行(或行)进行更新。默认情况下,
UPDATE
操作遍历表中的所有行,并更新满足条件表达式的所有行。如果没有行满足条件表达式,
UPDATE
将成功完成并设置SQLCODE=100
(不再有数据)。可以指定
WHERE
子句或WHERE CURRENT OF
子句(但不能同时指定两者)。如果使用了
WHERE CURRENT OF
子句,UPDATE
将更新游标当前位置的记录。定位操作请参见
WHERE CURRENT OF
。
UPDATE
操作将%ROWCOUNT
局部变量设置为更新的行数,将%ROWID
局部变量设置为更新的最后一行的ROWID
值。默认情况下,
UPDATE
操作是一个全有或全无事件。
要么更新所有指定的行和列,要么不更新。
INSERT OR UPDATE
INSERT OR UPDATE
语句是INSERT
语句的变体,执行插入和更新操作。首先,它尝试执行一个插入操作。
如果插入请求失败由于违反唯一键(字段(
s
)的一些独特的关键,存在这一行已经有相同的值(s
)为插入指定的行),然后它会自动变成一个更新请求这一行,并插入或更新使用指定的字段值来更新现有的行。
SQLCODE错误
默认情况下,多行UPDATE是一个原子操作。
如果不能更新一行或多行,则UPDATE
操作失败,不会更新任何行。IRIS设置
SQLCODE
变量,该变量指示UPDATE
的成功或失败,如果操作失败,还设置%msg
。
要更新表,更新必须满足所有表、列名和值要求,如下所示。
表:
- 表必须存在于当前(或指定)命名空间中。
如果无法找到指定的表,IRIS将发出SQLCODE -30
错误。
- 该表不能定义为
READONLY
。
试图编译引用只读表的UPDATE
会导致SQLCODE -115
错误。注意,此错误是在编译时发出的,而不是在执行时发生的。
请参阅定义和使用类的其他持久化类选项章节中
READONLY
对象的描述。
- 该表不能被其他进程以
EXCLUSIVE
模式锁定。
试图更新一个被锁定的表将导致SQLCODE -110
错误,并带有%msg
,如下所示:
Person' on row with RowID = '10'
。注意,只有当
UPDATE
语句定位到要更新的第一条记录,然后不能在超时时间内锁定它时,才会出现SQLCODE -110
错误。
- 如果UPDATE指定了一个不存在的字段,则会发出
SQLCODE -29
。
要列出为指定表定义的所有字段名。
如果字段存在,但没有字段值满足UPDATE
命令的WHERE
子句,则不影响任何行,并发出SQLCODE 100
(数据末尾)。
- 在极少数情况下,使用
%NOLOCK
的UPDATE
找到要更新的行,但随后该行立即被另一个进程删除;
这种情况将导致SQLCODE -109
错误:无法找到为UPDATE
指定的行。这个错误的
%msg
列出了表名和RowID
。
- 如果通过视图更新表,则视图不能定义为
WITH READ ONLY
。
尝试这样做会导致SQLCODE -35
错误。如果视图基于分片表,则不能通过定义
WITH CHECK OPTION
的视图进行UPDATE
。尝试这样做会导致一个
SQLCODE -35
,其中%msg INSERT/UPDATE/DELETE
不允许查看(sample.myview
)基于带有检查选项条件的分片表。
列名和值:
- 更新不能包含重复的字段名。
尝试指定两个具有相同名称的字段的更新将导致SQLCODE -377
错误。
- 不能更新已被另一个并发进程锁定的字段。
尝试这样做会导致SQLCODE -110
错误。如果执行的更新数量非常大,以致出现
错误,也会发生此SQLCODE
错误。
- 不能更新整数计数器字段。
这些字段是不可修改的。
RowID
字段(SQLCODE -107
);
IDENTITY
字段(SQLCODE -107
);
SERIAL (%Library.Counter)
字段(SQLCODE -105
);
ROWVERSION
字段(SQLCODE -138
)。这些字段的值是系统生成的,用户不能修改。
即使用户可以为计数器字段插入一个初始值,用户也不能更新该值。
唯一的例外是将
SERIAL (%Library.Counter)
字段添加到具有现有数据的表时。对于这个添加的计数器字段,现有的记录将具有NULL值。
在这种情况下,可以使用
UPDATE
将NULL
更改为整数值。
- 不能更新
shard
键字段。
尝试更新属于分片键一部分的字段会产生SQLCODE -154
错误。
- 如果更新将违反字段的唯一性约束,则不能更新字段值。
试图更新一个字段(或一组字段)的值,使更新违反惟一性约束或主键约束,将导致SQLCODE -120
错误。如果字段具有UNIQUE数据约束,或者如果惟一字段约束已应用于一组字段,则返回此错误。
SQLCODE - 120% msg
字符串包括违背唯一性约束的字段和值。例如
or
。
- 如果更新指定的值不在其
VALUELIST
参数中列出,则不能更新字段值。
用VALUELIST
参数定义的持久化类的属性只能接受VALUELIST
中列出的值中的一个作为有效值,或者不提供值(NULL
)。
VALUELIST
有效值区分大小写。尝试使用与
VALUELIST
值不匹配的数据值进行更新会导致SQLCODE -105
字段值验证失败错误。
- 数字以规范形式插入,但可以用前导零和尾随零以及多个前导符号来指定。
然而,在SQL中,两个连续的负号被解析为单行注释指示符。
因此,试图指定具有两个连续前导减号的数字将导致SQLCODE -12
错误。
- 当使用
WHERE CURRENT OF
子句时,不能使用当前字段值更新字段以生成更新的值。
例如,SET Salary=Salary+100
或SET Name=UPPER(Name)
。尝试这样做会导致
SQLCODE -69
错误:SET = not allowed with WHERE CURRENT OF
。
- 如果更新其中一个指定的行会违反外键引用完整性(并且没有指定
%NOCHECK
), UPDATE
将无法更新任何行,并发出SQLCODE -124
错误。
如果外键是用NOCHECK
关键字定义的,则不适用。
- 不能用流数据更新非流字段。
这将导致SQLCODE -303
错误,如下所述。
可以通过多种方式为指定的列分配新值。
- 使用
SET
关键字,将一个或多个列=标量表达式对指定为逗号分隔的列表。
例如:
SET StatusDate='05/12/06',Status='Purged'
- 使用
VALUES
关键字,指定与相应的标量表达式列表相等的列列表。
例如:
(StatusDate,Status) VALUES ('05/12/06','Purged')
当将标量表达式值赋给列列表时,每个指定的列必须有一个标量表达式。
- 使用不带列列表的
VALUES
关键字,指定一个按列顺序隐式对应于行的列的标量表达式列表。
下面的示例指定了表中的所有列,指定了一个文本值来更新Address列:
VALUES (Name,DOB,'22 Main St. Anytown MA 12345',SSN)
在为隐式列列表赋值时,必须按照DDL
中定义的列的顺序为每个可更新字段提供一个值。(没有指定不可更新的
RowID
列。)
这些值可以是指定新值的文字,也可以是指定现有值的字段名。
不能指定占位符逗号或省略尾随字段。
- 使用不带列列表的
VALUES
关键字,指定下标数组,其中数字下标对应列号,包括在列计数中不可更新的RowID
作为列号1。
例如:
VALUES :myarray()
只能使用主机变量在嵌入式SQL
中执行此值赋值。与所有其他值赋值不同,这种用法允您延迟指定哪些列要更新到运行时(通过在运行时填充数组)。
所有其他类型的更新都要求必须在编译时指定要更新的列。
此语法不能用于链接表;
尝试这样做会导致
SQLCODE=-155
错误。