sqlserver 的 update table set field= 居然可以返回多个值,若符合条件的话,这岂不是很要命?

handsome1234 2016-12-15 09:05:22
今日发现sqlserver 的 update table set field= 居然可以返回多个值,若符合条件的话,这岂不是很要命?
ORACLE update 若返回多个,会直接报错的。


UPDATE xtm12 --
SET xtm12.xtysmc = LTRIM(RTRIM(xtm12.xtysmc))
+ LTRIM(RTRIM(CCC.xtpssm)) --
FROM dbo.dhm42 CCC
WHERE CCC.xtpzgg = xtm12.xtpzgg
AND ( LEN(LTRIM(RTRIM(xtm12.xtysmc)) + LTRIM(RTRIM(CCC.xtpssm))) < 45 )
AND ( CHARINDEX(LTRIM(RTRIM(CCC.xtpssm)), xtm12.xtysmc) = 0 )
AND xtm12.xtysmc IS NOT NULL
AND LTRIM(RTRIM(CCC.dhyydm)) = LTRIM(RTRIM(xtm12.wpsxlb2))
...全文
246 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
中国风 2016-12-16
  • 打赏
  • 举报
回复
引用 8 楼 handsome1234 的回复:
数据的问题,是数据库开发人员处理的事,同数据库无关,不同数据库有不同的特性,同一个数据库不同版本都会有所不同 要用某一款数据库就要去适应这数据库的语法和规则 比如:曾遇到有用户用SQL2005升级到2008时,发现有接口报错,查出原因由于05和08版本引擎发生变化,改变了执行计划的顺序,造成报错。这类你找软件提供商?没人知道供应商下一版本会改变什么,这是不只预知的
Tiger_Zhao 2016-12-16
  • 打赏
  • 举报
回复
你认为多条不行,更新前先判断下面的 errCnt,自己报错。
SELECT COUNT(*) errCnt
FROM (
SELECT #t1.id,
COUNT(*) cnt
FROM #t1
JOIN #t2
ON #t1.id = #t2.fid
GROUP BY #t1.id
HAVING COUNT(*) > 1
) T
中国风 2016-12-16
  • 打赏
  • 举报
回复
看了一下 --所谓第1条和最后1条要看执行计划是用到的索引(顺序/倒序)或表扫描等因素而定 赋值时 表最后1条记录(取所有成立记录(All),最后1条) 更新时 表第1条记录(条件任何有1条满足条件就成立,取这1条成立数据(Any)) ------影响因素不同,影响取值.
handsome1234 2016-12-16
  • 打赏
  • 举报
回复

DROP TABLE #t1
DROP TABLE #t2

CREATE TABLE #t1(id int, xtysmc varchar(10))
INSERT INTO #t1 VALUES(1,'A')

CREATE TABLE #t2(fid int, xtpssm varchar(10))
INSERT INTO #t2 VALUES(1,'B')
INSERT INTO #t2 VALUES(1,'C')

UPDATE #t1
   SET #t1.xtysmc = #t1.xtysmc + #t2.xtpssm
  FROM #t2
 WHERE #t1.id = #t2.fid  --其中满足这条件,如果#t2.xtpssm能返回行数大于2行,这本身就是有问题。
--oracle 会直接报错的。这也给数据带来很多不确定性。

SELECT * FROM #t1
  • 打赏
  • 举报
回复
实验了下 真的存在这种问题,而且是取得是第一条数据的值。
Tiger_Zhao 2016-12-16
  • 打赏
  • 举报
回复
DROP TABLE #t1
DROP TABLE #t2

CREATE TABLE #t1(id int, xtysmc varchar(10))
INSERT INTO #t1 VALUES(1,'A')

CREATE TABLE #t2(fid int, xtpssm varchar(10))
INSERT INTO #t2 VALUES(1,'B')
INSERT INTO #t2 VALUES(1,'C')

UPDATE #t1
SET #t1.xtysmc = #t1.xtysmc + #t2.xtpssm
FROM #t2
WHERE #t1.id = #t2.fid

SELECT * FROM #t1

         id xtysmc
----------- ----------
1 AB

看来是用第一条
handsome1234 2016-12-16
  • 打赏
  • 举报
回复
看来是存在这个问题。 老大说了,能接受这个数据库,那就要努力适应。不行就换数据库。
中国风 2016-12-15
  • 打赏
  • 举报
回复
可以用以下测测,测时加上事务--回滚更新效果,合并值


e.g.


UPDATE xtm12 --
SET xtm12.xtysmc = LTRIM(RTRIM(xtm12.xtysmc))
+ ( SELECT LTRIM(RTRIM(CCC.xtpssm)) + '' --我的意思是说,如果CCC.xtpssm有多个值符合条件,那具体使用的是哪个就是不是随机了?
FROM dbo.dhm42 CCC
WHERE CCC.xtpzgg = xtm12.xtpzgg
AND ( LEN(LTRIM(RTRIM(xtm12.xtysmc))
+ LTRIM(RTRIM(CCC.xtpssm))) < 45 )
AND ( CHARINDEX(LTRIM(RTRIM(CCC.xtpssm)), xtm12.xtysmc) = 0 )
AND xtm12.xtysmc IS NOT NULL
AND LTRIM(RTRIM(CCC.dhyydm)) = LTRIM(RTRIM(xtm12.wpsxlb2))
FOR
XML PATH('')
)
WHERE EXISTS ( SELECT 1
FROM dbo.dhm42 DDD
WHERE DDD.xtpzgg = xtm12.xtpzgg
AND ( LEN(LTRIM(RTRIM(xtm12.xtysmc))
+ LTRIM(RTRIM(DDD.xtpssm))) < 45 )
AND ( CHARINDEX(LTRIM(RTRIM(DDD.xtpssm)), xtm12.xtysmc) = 0 )
AND xtm12.xtysmc IS NOT NULL
AND LTRIM(RTRIM(DDD.dhyydm)) = LTRIM(RTRIM(xtm12.wpsxlb2)) );

中国风 2016-12-15
  • 打赏
  • 举报
回复
dhm42 --表的默认顺序满足条件最后一个值,看执行计划 -------------- 要多个值合并时,用for xml生成更新值
中国风 2016-12-15
  • 打赏
  • 举报
回复
xtpssm--列的表顺序
handsome1234 2016-12-15
  • 打赏
  • 举报
回复

UPDATE  xtm12  --
        SET     xtm12.xtysmc = LTRIM(RTRIM(xtm12.xtysmc))
                + LTRIM(RTRIM(CCC.xtpssm))   --我的意思是说,如果CCC.xtpssm有多个值符合条件,那具体使用的是哪个就是不是随机了?
        FROM    dbo.dhm42 CCC
        WHERE   CCC.xtpzgg = xtm12.xtpzgg
                AND ( LEN(LTRIM(RTRIM(xtm12.xtysmc)) + LTRIM(RTRIM(CCC.xtpssm))) < 45 )
                AND ( CHARINDEX(LTRIM(RTRIM(CCC.xtpssm)), xtm12.xtysmc) = 0 )
                AND xtm12.xtysmc IS NOT NULL                
                 AND LTRIM(RTRIM(CCC.dhyydm)) =  LTRIM(RTRIM(xtm12.wpsxlb2)) 
tcmakebest 2016-12-15
  • 打赏
  • 举报
回复
到底说的什么意思, UPDATE返回一个值就是更新的记录数, 没有任何问题.

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧