第五十六章 SQL命令 INSERT OR UPDATE
文章目录
- 第五十六章 SQL命令 INSERT OR UPDATE
- 大纲
- 参数
- 描述
- 权限
- IDKEY字段
- 计数器字段
- Identity和RowID字段
- 示例
第五十六章 SQL命令 INSERT OR UPDATE
在表中添加新行或更新表中的现有行。
大纲
INSERT OR UPDATE [%keyword] [INTO] tableSET column = scalar-expression {,column2 = scalar-expression2} ... |[ (column{,column2} ...) ] VALUES (scalar-expression {,scalar-expression2} ...) |VALUES :array() |[ (column{,column2} ...) ] query |DEFAULT VALUES
参数
%keyword
- 可选-以下一个或多个关键字选项,以空格分隔:%NOCHECK
、%NOFPLAN
、%NOINDEX
、%NOJOURN
、%NOLOCK
、%NOTRIGGER
、%PROFILE
、%PROFILE_ALL
。table
- 要对其执行插入操作的表或视图的名称。此参数可以是子查询。INTO
关键字是可选的。column
- 可选-与提供的值列表顺序对应的列名或以逗号分隔的列名列表。如果省略,值列表将按列号顺序应用于所有列。scalar-expression
- 为相应列字段提供数据值的标量表达式或以逗号分隔的标量表达式列表。:array()
- 仅嵌入式SQL-指定为主机变量的值的动态本地数组。必须未指定数组的最低下标级别。因此:myupdates()
,:myupdates(5,)
和:myupdates(1,1,)
都是有效的规范。query
- 一种选择查询,其结果集为一行或多行的相应列字段提供数据值。
描述
INSERT
或UPDATE
语句是INSERT
语句的扩展(它与INSERT
语句非常相似):
- 如果指定的记录不存在,则
INSERT
或UPDATE
执行INSERT
。 - 如果指定的记录已存在,则
INSERT
或UPDATE
执行更新。它使用指定的字段值更新记录。即使指定的数据与现有数据相同,也会进行更新。
INSERT
或UPDATE
通过将唯一关键字字段值与现有数据值匹配来确定记录是否存在。如果发生违反唯一键约束的情况,则INSERT
或UPDATE
将执行UPDATE
操作。请注意,唯一键字段值可能不是在INSERT
或UPDATE
中显式指定的值;它可能是列默认值或计算值的结果。当对切片表运行INSERT
或UPDATE
时,如果切片键与UNIQUE KEY
约束相同(或是其子集),则INSERT
或UPDATE
将执行UPDATE
操作。如果INSERT
或UPDATE
因为找到任何其他唯一键值(不是切片键)而尝试执行更新,则该命令会失败,并由于UNIQUE
约束失败而出现SQLCODE-119
错误。
注意:由于%NOCHECK
关键字禁用唯一值检查,因此INSERT
或UPDATE %NOCHECK
总是导致INSERT
操作。因此,请不要指定%NOCHECK
。
单个记录的INSERT
或UPDATE
始终将%ROWCOUNT
变量设置为1,并将已插入或更新的行的%ROWID
变量设置为1。
INSERT
或UPDATE
语句与SELECT
语句组合可以插入和/或更新多个表行。
INSERT
或UPDATE
使用相同的语法,并且通常具有与INSERT
语句相同的功能和限制。这里描述了插入或更新的特殊注意事项。除非此处另有说明,否则请参阅插入以了解详细信息。
权限
INSERT
或UPDATE
同时需要插入和更新权限。必须将这些权限作为表级权限或列级权限拥有。对于表级权限:
- 无论实际执行的是什么操作,用户都必须拥有对指定表的
INSERT
和UPDATE
权限。 - 如果使用
SELECT
查询插入或更新另一个表中的数据,则用户必须对该表具有SELECT
权限。
如果用户是表的所有者(创建者),则会自动授予该用户对该表的所有权限。否则,必须授予用户对该表的权限。否则将导致SQLCODE-99
错误,因为%msg
用户‘name’
没有该操作的特权。可以通过调用%CHECKPRIV
命令来确定当前用户是否具有适当的权限。可以使用GRANT
命令为用户分配表权限。
IDKEY字段
可以插入IDKEY
字段值,但不能更新IDKEY
字段值。如果表具有IDKEY
索引和另一个唯一键约束,则INSERT
或UPDATE
将匹配这些字段以确定是执行INSERT
还是UPDATE
。如果另一个键约束失败,则强制INSERT
或UPDATE
执行更新而不是INSERT
。但是,如果指定的IDKEY
字段值与现有IDKEY
字段值不匹配,则此更新将失败并生成SQLCODE-107
错误,因为更新正在尝试修改IDKEY
字段。
例如,表MyTest
定义了四个字段:A、B、C、D
,具有IDKEY(A,B)
和Unique(C,D)
约束。该表包含以下记录:
Row 1: A=1, B=1, C=2, D=2Row 2: A=1, B=2, C=3, D=4
调用INSERT
或UPDATE ABC(A,B,C,D)
值(2,2,3,4)
,因为UNIQUE(C,D)
约束失败,所以该语句不能执行INSERT
。相反,它会尝试更新第2
行。第2
行的IDKEY为(1,2)
,因此INSERT
或UPDATE
语句将尝试将字段A
的值从1更改为2。但无法更改IDKEY
值,因此更新失败,并显示SQLCODE-107
错误。
计数器字段
当执行INSERT
或UPDATE
时, IRIS最初假定操作将是INSERT
。因此,它将用于向串行(%Library.Counter
)字段提供整数的内部计数器加1。INSERT
使用这些递增的计数器值将整数值分配给这些字段。但是,如果 IRIS确定该操作需要更新,则INSERT
或UPDATE
已经递增了内部计数器,但它不会将这些递增的整数值分配给计数器字段。如果下一个操作是INSERT
,则会导致这些字段的整数序列出现间隙。下面的示例显示了这一点:
- 内部计数器值为
4
。INSERT
或UPDATE
递增内部计数器,然后插入行5
:内部计数器=5
,串行字段值=5
。 INSERT
或UPDATE
递增内部计数器,然后确定它必须对现有行执行更新:INTERNAL COUNTER=6
,不更改字段计数器。INSERT
或UPDATE
递增内部计数器,然后插入一行:内部计数器=7
,序列字段值=7
。
Identity和RowID字段
INSERT
或UPDATE
对RowId
值分配的影响取决于是否存在标识字段:
- 如果没有为表定义标识字段,则
INSERT
操作会导致 IRIS自动将下一个连续整数值分配给ID(RowID)
字段。更新操作对后续插入没有影响。因此,INSERT
或UPDATE
执行与INSERT
相同的INSERT
操作。 - 如果为表定义了标识字段,则
INSERT
或UPDATE
会导致 IRIS在确定操作是INSERT
还是UPDATE
之前,将用于向标识字段提供整数的内部计数器加1
。插入操作将该递增的计数器值分配给标识字段。但是,如果 IRIS确定INSERT
或UPDATE
操作需要更新,则它已经递增了内部计数器,但不会分配这些递增的整数值。如果下一个INSERT
或UPDATE
操作是INSERT
,则会导致标识字段的整数序列出现间隙。RowID
字段值取自Identity
字段值,导致ID(RowID)
整数值的分配存在差距。
示例
以下五个示例:创建一个新表(SQLUser.CaveDwell
);使用INSERT
或UPDATE
用数据填充该表;使用INSERT
或UPDATE
添加新行并更新现有行;使用SELECT*
显示数据;以及删除该表。
以下示例使用CREATE TABLE
创建具有唯一字段(NUM
)的表:
ClassMethod InsertOrUpdate()
{&sql(CREATE TABLE SQLUser.CaveDwellers (Num INT UNIQUE,CaveCluster CHAR(80) NOT NULL,Troglodyte CHAR(50) NOT NULL,CONSTRAINT CaveDwellerPK PRIMARY KEY (Num)))if SQLCODE = 0 { w !,"表创建" } elseif SQLCODE = -201 { w !,"表已经存在" } else { w !,"SQL表创建错误代码: ",SQLCODEq }
}
下面的示例使用类定义定义同一个表,为num
定义唯一键:
Class User.CaveDwellers Extends %Persistent [ ClassType = persistent, DdlAllowed, Final, Owner = {yx}, ProcedureBlock, SqlRowIdPrivate, SqlTableName = CaveDwellers ]
{Property Num As %Library.Integer(MAXVAL = 2147483647, MINVAL = -2147483648) [ SqlColumnNumber = 2 ];Property CaveCluster As %Library.String(MAXLEN = 80) [ Required, SqlColumnNumber = 3 ];Property Troglodyte As %Library.String(MAXLEN = 50) [ Required, SqlColumnNumber = 4 ];/// DDL Unique Key Specification
Index CAVEDWELLERSUNIQUE1 On Num [ SqlName = CAVEDWELLERS_UNIQUE1, Unique ];/// DDL Primary Key Specification
Index CaveDwellerPK On Num [ PrimaryKey, Type = index, Unique ];/// Bitmap Extent Index auto-generated by DDL CREATE TABLE statement. Do not edit the SqlName of this index.
Index DDLBEIndex [ Extent, SqlName = "%%DDLBEIndex", Type = bitmap ];}
SELECT * FROM SQLUser.CaveDwellers ORDER BY Num
以任何顺序运行以下两个示例一次或多次。他们将插入记录1
到5
。如果记录4
已经存在,插入或更新将更新它。使用SELECT *
示例显示表格数据:
ClassMethod InsertOrUpdate1()
{&sql(INSERT OR UPDATE INTO SQLUser.CaveDwellers (Num, CaveCluster, Troglodyte) VALUES (3, 'Bedrock', 'Flintstone,Fred'))if SQLCODE = 0 { SET rcount=%ROWCOUNT }&sql(INSERT OR UPDATE INTO SQLUser.CaveDwellers (Num, CaveCluster, Troglodyte) VALUES (4, 'Bedrock1', 'Flintstone,Wilma'))if SQLCODE = 0 { s rcount = rcount + %ROWCOUNT w !,rcount," records inserted/updated" } else { w !,"Insert/Update failed, SQLCODE=",SQLCODE }
}
ClassMethod InsertOrUpdate2()
{n SQLCODE,%ROWCOUNT,%ROWID&sql(INSERT OR UPDATE SQLUser.CaveDwellers(Num,CaveCluster,Troglodyte)SELECT %ID,Home_City,NameFROM Sample.PersonWHERE %ID BETWEEN 2 AND 5)if SQLCODE=0 {w !,"Insert/Update succeeded"w !,%ROWCOUNT," records inserted/updated"w !,"Row ID=",%ROWID } else {w !,"Insert/Update failed, SQLCODE=",SQLCODE }
}
以下示例删除该表:
ClassMethod InsertOrUpdate3()
{&sql(DROP TABLE SQLUser.CaveDwellers)if SQLCODE = 0 {w !,"表已删除" } elseif SQLCODE = -30 {w !,"表不存在"} else {w !,"删除表失败. SQLCODE=",SQLCODE }
}
第五十六章 SQL命令 INSERT OR UPDATE相关推荐
- 第五十二章 SQL命令 INSERT(一)
文章目录 第五十二章 SQL命令 INSERT(一) 大纲 参数 描述 INSERT OR UPDATE %Keyword字选项 表参数 赋值 值赋值语法 显示到逻辑数据的转换 %SerialObje ...
- 第十六章 SQL命令 CREATE TABLE(三)
文章目录 第十六章 SQL命令 CREATE TABLE(三) 字段数据约束 NULL和NOT NULL UNIQUE DEFAULT DEFAULT Keywords ON UPDATE Colla ...
- 第七十六章 SQL命令 TOP
文章目录 第七十六章 SQL命令 TOP 大纲 参数 描述 TOP int值 TOP和缓存查询 TOP和ORDER BY TOP 优化 TOP与聚合和函数 示例 第七十六章 SQL命令 TOP 指定返 ...
- 第六十六章 SQL命令 REVOKE
文章目录 第六十六章 SQL命令 REVOKE 大纲 参数 描述 撤销的角色 撤销对象权限 撤销对象所有者特权 撤销表级和列级特权 CASCADE 或 RESTRICT 对缓存查询的影响 IRIS S ...
- 第八十六章 SQL命令 USE DATABASE
文章目录 第八十六章 SQL命令 USE DATABASE 大纲 参数 描述 通过xDBC执行 第八十六章 SQL命令 USE DATABASE 设置当前名称空间和数据库. 大纲 USE [DATAB ...
- 第六十二章 SQL命令 OPEN
文章目录 第六十二章 SQL命令 OPEN 大纲 参数 描述 示例 第六十二章 SQL命令 OPEN 打开游标. 大纲 OPEN cursor-name 参数 cursor-name - 游标的名称, ...
- 第六章 SQL命令 CREATE INDEX(一)
文章目录 第六章 SQL命令 CREATE INDEX(一) 大纲 参数 描述 权限与锁 仅支持兼容性选项 索引名称 现有索引 表明 字段名称 嵌入对象中的字段(`%SerialObject`) 索引 ...
- 第二十二章 SQL命令 CREATE TRIGGER(二)
文章目录 第二十二章 SQL命令 CREATE TRIGGER(二) SQL触发器代码 ObjectScript触发代码 字段引用和伪字段引用 引用流属性 引用SQLComputed属性 标签 方法调 ...
- 第三十六章 SQL函数 CURRENT_TIME
文章目录 第三十六章 SQL函数 CURRENT_TIME 大纲 参数 描述 小数秒精度 示例 第三十六章 SQL函数 CURRENT_TIME 返回当前本地时间的日期/时间函数. 大纲 CURREN ...
最新文章
- 九种食物帮你赶走忧郁
- python测试开发自学教程-python测试开发学习笔记
- qt creator 信号与槽 代码实现 (二)
- python PyQt5 QFrame类
- 0b3398php,思想道德修养与法律基础(九江职业技术学院)知到2020题目及答案
- c#语言输出字符串长度,根据宽度来决定显示的字符串长度(C#)
- Pytorch与Tensorflow,哪个更适合你?
- Spark内置图像数据源初探
- php位运算符与逻辑运算_位运算符及PHP中位运算的应用笔记
- 3rd,Python登录模拟
- 接口测试——Fiddler使用要点——笔记整理
- 前后端开源的一款简单的微信个人博客小程序
- 灰度图像加性噪声污染和运动模糊图像复原
- 信捷PLC Modbus通讯 (Modbus_TCP与Modbus_RTU)
- matlab中3乘4魔方阵,小代码3 魔方矩阵
- 网页直接加QQ群/QQ好友
- weka下载安装以及源码运行
- 爬取今日头条新闻,并导入execle中(主要用了selenium)
- 内涵社区APP,一款集内涵段子,百思不得其姐,煎蛋于一身的搞笑社区
- perl use和require的用法