======== sql编程应该依赖异常吗? ============

愚者只看星不看答案 2016-11-04 05:09:34
设一张表中 手机号码 字段有唯一索引
当在存储过程中,新增一个手机号码时,请问大家是采用begin try end try 这样的异常处理机制,在begin catch中 返回值(return)
还是说自己先用 if exists 这样的语句进行判断,当if exists发现不是唯一时,再返回值

问这个问题是因为其它的编程语言中一直在强调不要依赖于异常处理。

多谢。

@roy_88 @wmxcn2000
...全文
413 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
专注or全面 2016-11-07
  • 打赏
  • 举报
回复
引用 8 楼 truelove12 的回复:
感谢大家的回复。如果一个表中有两个字段都各有一个唯一索引 如果不写if exists,直接做insert操作,然后在begin catch中捕获错误的话,那么在这中间,你是无法知道到底是违反了哪一个唯一性约束,也就无法给应用程序提供足够的有用信息,大家怎么看。多谢。
是的,业务相关的逻辑需要你自己去做处理,这种事太过于明显的业务校验问题,根本就不属于异常处理的范围和职业 即便不在同一个存储过程的SQL里处理,也需要在别的地方(读取数据库)校验。 我还是自己的意见,效率高低是一回事,异常处理是一回事,一场处理的作用并不是替代最基本的逻辑校验的。
  • 打赏
  • 举报
回复
感谢大家的回复。如果一个表中有两个字段都各有一个唯一索引 如果不写if exists,直接做insert操作,然后在begin catch中捕获错误的话,那么在这中间,你是无法知道到底是违反了哪一个唯一性约束,也就无法给应用程序提供足够的有用信息,大家怎么看。多谢。
中国风 2016-11-05
  • 打赏
  • 举报
回复
begin catch直接获取错误信息 不想暴露数据库的数据信息时,只能在程序自定义错误信息时,可用RETURN定义统一值如“数据错误:请联系管理员” 注:多个DML语句时操作数据时要加上事务 不需要IF EXISTS,这样影响性能,每次都需要去检查一下,不推荐用
中国风 2016-11-05
  • 打赏
  • 举报
回复
采用begin try end try ---------
卖水果的net 版主 2016-11-05
  • 打赏
  • 举报
回复
手机号是否合法,建议在前台程序进行处理; 比如对文本框使用正则表达式的验证,或者使用加自己的验证方法;
  • 打赏
  • 举报
回复
@wmxcn2000 感谢回复。 我换一人说法,设一个手机号码字段是 nchar(11),这个字段上有一个检查约束,要求每个字符都是介于0-9之间 假设插入语句是这样的 insert into tablename(phonenumber) values(@phonenumber); 你一般会在这个语句前对@phonenumber进行编程检查(以满足检查约束的要求),还是说对@phonenumber不检查,而直接使用 begin try end try 这样的做法,直接捕捉错误呢。。多谢。 此处不考虑应用程序做不做检查的事情。
专注or全面 2016-11-05
  • 打赏
  • 举报
回复
写不写EXISTS跟异常处理没关系,那是你的业务问题,效率高不高纯属设计问题 直说该不该依赖于异常:回答是该!!! 能够预料到的都不是异常,异常处理是处理的预料不到的并且是非灾难性的异常 我个人理解, 所谓预料不到的,比如是存储空间问题,执行了批处理一部分之后,数据文件满了且不允许增加,无法继续进行写入操作了 此时就需要在catch块中记录这个异常,便于问题排查 所谓非灾难性的,比如发洪水冲了机房,再怎么异常处理,都无济于事
卖水果的net 版主 2016-11-04
  • 打赏
  • 举报
回复

-- 或者使用 merge 语法也可以的

create table test(phone varchar(10))
go
create unique index ix_test on test(phone)
go
print '-- 第一次写入'
merge into test
using (select '110' c ) c on test.phone = c.c 
when not matched then
insert (phone) values(c.c);

select @@ROWCOUNT c
go

print '-- 第二次写入'
merge into test
using (select '110' c ) c on test.phone = c.c 
when not matched then
insert (phone) values(c.c);
select @@ROWCOUNT c
go

select * from test 
go
drop table test 
go

-- 第一次写入

(1 行受影响)
c
-----------
1

(1 行受影响)

-- 第二次写入

(0 行受影响)
c
-----------
0

(1 行受影响)

phone
----------
110

(1 行受影响)


卖水果的net 版主 2016-11-04
  • 打赏
  • 举报
回复

create table test(phone varchar(10))
go
create unique index ix_test on test(phone)
go
print '-- 第一次写入'
insert into test(phone)
select '110'
where not exists(select * from test where phone = '110')
select @@ROWCOUNT c
go

print '-- 第二次写入'
insert into test(phone)
select '110'
where not exists(select * from test where phone = '110')
select @@ROWCOUNT c
go

select * from test 
go
drop table test 
go


-- 第一次写入

(1 行受影响)
c
-----------
1

(1 行受影响)

-- 第二次写入

(0 行受影响)
c
-----------
0

(1 行受影响)

phone
----------
110

(1 行受影响)


34,590

社区成员

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

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