update中加入select 完成查询更新

update中加入select

最常用的update语法是:
UPDATE <table_name>
SET <column_name1> = <value>, SET <column_name2> = <value>

如果我的更新值Value是从一条select语句拿出来,而且有很多列的话,用这种语法就很麻烦
第一,要select出来放在临时变量上,有很多个哦
第二,再将变量进行赋值。
列多起来非常麻烦,能不能像Insert那样,把整个Select语句的结果进行插入呢?就好象下面
insert into table1
(c1, c2, c3)
(select v1, v2, v3 from table2)

答案是可以的,具体的语法如下:
UPDATE <table_name> <alias>
SET (<column_name>,<column_name> ) = (
SELECT (<column_name>, <column_name>)
FROM <table_name>
WHERE <alias.column_name> = <alias.column_name>)
WHERE <column_name> <condition> <value>;

下面是这样一个例子:

两个表a、b,想使b中的memo字段值等于a表中对应id的name值
表a:id, name
1 王
2 李
3 张
表b:id,ClientName   
            1
2
3
(MS SQL Server)语句:update b   set   ClientName    = a.name    from a,b    where a.id = b.id  

(Oralce)语句:update b   set   (ClientName)    =   (SELECT name FROM a WHERE b.id = a.id)

update set from 语句格式

当where和set都需要关联一个表进行查询时,整个update执行时,就需要对被关联的表进行两次扫描,显然效率比较低。
对于这种情况,Sybase和SQL SERVER的解决办法是使用UPDATE...SET...FROM...WHERE...的语法,实际上就是从源表获取更新数据。

在 SQL 中,表连接(left join、right join、inner join 等)常常用于 select 语句,其实在 SQL 语法中,这些连接也是可以用于 update 和 delete 语句的,在这些语句中使用 join 还常常得到事半功倍的效果。

Update T_OrderForm SET T_OrderForm.SellerID =B.L_TUserID
FROM T_OrderForm A LEFT JOIN T_ProductInfo   B ON B.L_ID=A.ProductID

用来同步两个表的数据!

Oralce和DB2都支持的语法:

UPDATE A SET (A1, A2, A3) = (SELECT B1, B2, B3 FROM B WHERE A.ID = B.ID)

MS SQL Server不支持这样的语法,相对应的写法为:
UPDATE A  SET A1 = B1, A2 = B2, A3 = B3  FROM A LEFT JOIN B ON A.ID = B.ID

个人感觉MS SQL Server的Update语法功能更为强大。MS SQL SERVER的写法:
UPDATE A SET A1 = B1, A2 = B2, A3 = B3 FROM A, B WHERE A.ID = B.ID

在Oracle和DB2中的写法就比较麻烦了,如下:

UPDATE A SET (A1, A2, A3) = (SELECT B1, B2, B3 FROM B WHERE A.ID = B.ID)
WHERE ID IN (SELECT B.ID FROM B WHERE A.ID = B.ID)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL查询相关技术,源码大放送! 10.1 SELECT子句 426   实例292 查询特定列数据 426   实例293 使用列别名 428   实例294 在列上加入计算 430 EX10_03   实例295 使用函数设置条件 431   10.2 查询常量 432   实例296 查询数字 433   实例297 查询字符串 434   实例298 查询日期数据 436   实例299 查询逻辑型数据 437   实例300 查询空数据 438   10.3 查询变量 440   实例301 利用变量查询字符串数据 440   实例302 利用变量查询型数据 441   实例303 利用变量查询日期型数据 442   10.4 模式查询 444   实例304 利用“_”通配符进行查询 444   实例305 利用“%”通配符进行查询 445   实例306 利用“[]”通配符进行查询 446   实例307 利用“[^]”通配符进行查询 448   实例308 复杂的模式查询 449   10.5 TOP和PERCENT限制查询结果 450   实例309 查询前10名数据 450   实例310 取出数据统计结果的前10名数据 451   实例311 查询销售量占前50%的图书信息 453   实例312 查询库存数量占后20%的图书信息 454   10.6 周期、日期查询 455   实例313 查询指定日期的数据 455   实例314 查询指定时间段的数据 457   实例315 按月查询数据 458   10.7 比较、逻辑、重复查询 460   实例316 查询数据大于指定条件的数据 460   实例317 NOT与谓词进行组合条件的查询 461   实例318 查询时不显示重复记录 463   实例319 列出数据的重复记录和记录条数 465   10.8 在查询使用OR和AND运算符 466   实例320 利用OR运算符进行查询 466   实例321 利用AND运算符进行查询 467   实例322 同时利用OR、AND运算符进行查询 469   10.9 排序、分组统计 471   实例323 数据分组统计(单列) 471   实例324 在分组查询使用ALL关键字 473   实例325 在分组查询使用CUBE运算符 475   实例326 在分组查询使用ROLLUP 477   实例327 对数据进行降序查询 479   实例328 对数据进行多条件排序 480   实例329 对统计结果进行排序 482   实例330 按仓库分组统计图书库存(多列) 483   实例331 多表分组统计 484   实例332 使用COMPUTE 485   实例333 使用COMPUTE BY 487   10.10 聚合函数 488   实例334 利用聚合函数SUM对销售额进行汇总 488   实例335 利用聚合函数AVG求某班学生的平均年龄 490   实例336 利用聚合函数MIN求销售额、利润最少的商品 492   实例337 利用聚合函数MAX求月销售额完成最多的员工 493   实例338 利用聚合函数COUNT求日销售额大于某的商品数 495   实例339 利用聚合函数First或Last求数据表第一条或最后一条记录 496   10.11 多表查询(连接查询) 498   实例340 利用FROM子句进行多表查询 498   实例341 使用表别名 499   实例342 合并多个结果集 501   10.12 嵌套查询 503   实例343 简单嵌套查询 503   实例344 复杂嵌套查询 504   实例345 嵌套查询查询统计的应用 506   10.13 子查询 508   实例346 用子查询做派生的表 508   实例347 用子查询作表达式 510   实例348 在Update语句应用子查询 511   10.14 联合语句Union 512   实例349 使用联合查询 512   实例350 多表联合查询 514   实例351 对联合查询后的结果进行排序 515   10.15 内联接查询 517   实例352 简单内联接查询 517   实例353 复杂内联接查询 518   实例354 使用内联接选择一个表与另一个表行相关的所有行 519   10.16 外联接查询 520   实例355 left outer join查询 521   实例356 right outer join查询 522   实例357 使用外联接进行多表联合查询 523   10.17 利用IN进行查询 525   实例358 用IN查询的记录信息 525   实例359 使用IN引入子查询限定查询范围 526   10.18 交叉表查询 527   实例360 利用Trasform分析数据 527   实例361 利用Trasform动态分析数据 529   实例362 静态交叉表(SQLServer 2000) 531   实例363 动态交叉表(SQLServer 2000) 533   10.19 函数查询 535   实例364 在查询语句使用格式化函数 536   实例365 在查询语句使用字符串函数 537   实例366 在查询使用日期函数 538   10.20 having语句应用 540   实例367 利用having语句过滤分组数据 540   实例368 having语句应用在多表查询 541   10.21 视图的应用 543   实例369 在C#应用视图 543   实例370 获取数据库的全部用户视图 544   实例371 通过视图修改数据 545   10.22 存储过程的应用 546   实例372 C#应用存储过程 546   实例373 应用存储过程添加数据 547   实例374 应用存储过程修改数据 549   实例375 应用存储过程删除数据 550   实例376 C#应用查询存储过程 551   实例377 获取数据库全部的存储过程 552   实例378 加密存储过程 553   10.23 触发器的应用 555   实例379 Insert触发器的应用 555   实例380 Update触发器在系统日志的应用 556   实例381 触发器的嵌套使用 557   实例382 获取数据库的触发器 559
这段代码是一个MySQL的触发器,用于在`td_orders`表插入新数据时,根据订单商品的价格和优惠信息自动计算订单金额,并更新商品的库存数量。具体实现过程如下: 1. 首先从`tb_grade`表查询当前用户对应的等级优惠信息,将结果存储在变量`o_zk`。 2. 然后从`tb_products`表查询商品的价格、库存数量和商品编号,将结果存储在变量`p_price`、`p_stock`和`p_no`。 3. 接着判断库存数量是否足够,如果不足则抛出一个异常,否则更新`tb_products`表对应商品的库存数量,并根据价格和优惠信息计算订单金额,更新`td_orders`表对应订单的`Omoney`字段。 4. 最后,该触发器执行完毕。 但是,运行后报错 `1442 - Can't update table 'td_orders' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.`,这是因为该触发器更新了`td_orders`表,而MySQL不允许在触发器更新触发该触发器的表。所以,需要修改代码使其不更新`td_orders`表,或者将更新操作放在触发器外部进行。 具体修改方法可以参考以下代码: ``` DROP TRIGGER IF EXISTS WW; DELIMITER // CREATE TRIGGER WW AFTER INSERT ON td_orders FOR EACH ROW BEGIN DECLARE p_price DECIMAL(10, 2); DECLARE o_zk INT; DECLARE p_no INT; DECLARE p_stock INT; SELECT Gdiscounts INTO o_zk FROM tb_grade WHERE Gno IN (SELECT Gno FROM tb_card WHERE Ino = NEW.Ino); SELECT Pprice, Pcount, pno INTO p_price, p_stock, p_no FROM tb_products WHERE pno = NEW.pno; IF p_stock < NEW.Ocount THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '库存不足,无法完成操作'; ELSE -- 更新商品库存数量 UPDATE tb_products SET Pcount = p_stock - NEW.Ocount WHERE pno = p_no; -- 在外部更新订单金额 UPDATE td_orders SET Omoney = p_price * o_zk WHERE Ino = NEW.Ino AND Oid = NEW.Oid; END IF; END // DELIMITER ; ``` 以上代码,我们将更新订单金额的操作放在了触发器外部进行,通过在更新语句加入`AND Oid = NEW.Oid`条件,确保只更新对应订单的金额。这样可以避免在触发器更新`td_orders`表而导致的错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值