6人参与 • 2026-08-03 • MsSqlserver
数据定义(ddl)决定数据库长什么样,而数据操作(dml)决定数据库每天在做什么。 对于绝大多数业务系统来说,真正运行最频繁的不是 create table,而是 insert、update、delete 等 dml 操作。
本文将系统介绍 sql server 中最常用的 dml(data manipulation language,数据操作语言)语句,包括 insert、update、delete、merge、output 的使用方法、典型业务场景、性能优化技巧以及生产环境中的注意事项。
dml(data manipulation language)即数据操作语言,主要负责对表中的数据进行新增、修改、删除和合并。
sql server 中最核心的 dml 语句包括:
可以把数据库比作一本账本:
insert 用于向表中写入新数据。
insert into 表名 (列1, 列2, ...) values (值1, 值2, ...);
insert into users
(
username,
email,
createtime
)
values
(
'tom',
'tom@test.com',
getdate()
);
适用于:
insert into users
(
username,
email
)
values
('alice','alice@test.com'),
('bob','bob@test.com'),
('jack','jack@test.com');
sql server 2008 起支持这种写法。
相比循环 insert,效率明显更高。
例如归档历史订单。
insert into orderhistory
(
orderid,
userid,
amount
)
select
orderid,
userid,
amount
from orders
where status='completed';
这种方式通常比程序循环导入快得多。
insert into users
(
username,
status
)
values
(
'jerry',
default
);
要求字段定义了默认值。
例如:
status int default 1
建议:
insert into table values(...)update 用于修改已有记录。
update 表名 set 列=值 where 条件;
update users set phone='13800001111' where userid=1001;
update orders set status='completed' where paystatus='paid';
典型应用:
支付成功后更新订单状态。
例如同步会员等级。
update u set u.levelname=l.levelname from users u inner join userlevel l on u.levelid=l.levelid;
这种 update 是 sql server 非常实用的扩展。
务必带 where 条件。
建议先执行:
select * from orders where status='pending';
确认影响范围后再:
update orders set status='processing' where status='pending';
这是 dba 最基本的操作规范。
delete 删除的是数据,而不是表。
delete from 表名 where 条件;
delete from users where userid=1001;
delete from orders where userid=-1;
很多开发环境都会保留这种测试账号。
delete from systemlog where createtime < dateadd(month,-6,getdate());
这是日志清理最常见的方式。
| 对比项 | delete | truncate |
|---|---|---|
| 删除方式 | 按行删除 | 整表快速清空 |
| where | 支持 | 不支持 |
| 日志 | 较多 | 较少 |
| identity | 不重置 | 重置 |
| 触发器 | 会触发 | 不触发 delete trigger |
一般来说:
如果存在外键引用,truncate 通常无法执行。
merge 可以一次完成:
因此也称 upsert。
merge target as t
using source as s
on t.id=s.id
when matched then
update ...
when not matched then
insert ...;
merge users as t
using tempusers as s
on t.userid=s.userid
when matched then
update set
t.username=s.username,
t.email=s.email
when not matched then
insert
(
userid,
username,
email
)
values
(
s.userid,
s.username,
s.email
);
非常适合:
每天 erp 导入库存:
merge productstock as t using importstock as s on t.productid=s.productid when matched then update set stock=s.stock when not matched then insert(productid,stock) values(s.productid,s.stock);
sql server 多个版本曾修复过 merge 的边界 bug,生产环境建议:
很多人不知道,sql server 可以直接返回本次 dml 操作的数据。
insert into users
(
username
)
output inserted.userid,
inserted.username
values
(
'lucy'
);
返回:
userid username
无需再次查询。
update orders set amount=amount+100 output deleted.amount as oldamount, inserted.amount as newamount where orderid=10;
其中:
非常适合:
delete from users output deleted.* where userid=100;
删除前的数据可以直接保存到日志表。
多个 dml 通常需要作为一个整体执行。
begin tran; update account set balance=balance-100 where userid=1; update account set balance=balance+100 where userid=2; commit;
发生异常:
rollback;
最佳实践:
select * from orders where status='pending';
确认无误后再执行修改。
对于百万级数据:
不要:
delete from orders;
建议:
while 1=1
begin
delete top (5000)
from orders
where createtime<'2023-01-01';
if @@rowcount=0 break;
end
批量删除能够有效减少锁竞争与事务日志压力。
where 条件字段建议建立索引。
否则:
update、delete 很容易全表扫描。
对于海量数据:
update users set status=0;
整个用户表都会被修改。
这是数据库事故中最常见的问题之一。
例如:
where userid='100'
如果 userid 为 int,sql server 可能发生隐式转换,影响索引使用,导致性能下降。
建议保持参数类型与字段类型一致。
错误写法:
where email=null
正确写法:
where email is null
同样:
is not null
而不是:
!= null
例如:
orders
引用
users
删除用户:
delete from users where userid=1;
如果订单仍存在,将提示外键冲突。
应:
假设每天凌晨需要同步外部订单,并归档已完成订单。
第一步:同步新增和更新订单
merge orders as t
using importorders as s
on t.orderid = s.orderid
when matched then
update set
t.amount = s.amount,
t.status = s.status
when not matched then
insert (orderid, userid, amount, status)
values (s.orderid, s.userid, s.amount, s.status);
第二步:记录变更日志
update orders
set status = 'archived'
output
inserted.orderid,
deleted.status,
inserted.status,
getdate()
into orderchangelog
where status = 'completed';
第三步:归档历史数据
insert into orderhistory select * from orders where status='archived'; delete from orders where status='archived';
整个流程建议放入事务中执行,并结合适当索引,确保同步、日志记录和归档的一致性。
不同版本对 dml 能力持续增强:
dml 是数据库开发中使用频率最高的一组 sql 语句,也是最容易因为误操作而引发生产事故的部分。掌握 insert、update、delete、merge 与 output 的正确使用方式,不仅能够完成日常的数据维护工作,更能编写出安全、高效、易维护的数据处理程序。
最后,牢记几条经验法则:
到此这篇关于sql server dml 操作的项目实战的文章就介绍到这了,更多相关sqlserver dml 操作内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论