sql存储过程的坑


一、存储过程

做过开发的都应该清楚,尤其是服务端开发,必然要和数据库有很深的渊源,尤其是很多业务需要操作数据库来完成,那么存储过程就是程序员必备的一项技能了。这篇文章中不去介绍存储过程的语法等是怎么去写,这个对于数据其他语言的人来说,很快就会上手


二、遇到的坑

最近编写存错过程的时候,遇到一个坑,虽然很简单,但是很多人可能开没注意到。
我们知道存储过程中也有if…else的语句可以供我们使用,当然也就离不来判断条件,比如 ‘大于‘ >’,不等于’<>‘等等。

我们来看一个语句·select 1 from test where name = ’john‘·这么一条语句,这条语句我们一般是用来当做判断条件的,返回结果为1则为真,不为1则假,当然,不存在一般就是空了。

接下来,看一下存储过程的代码:

USE [test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date,,>
-- Description:	<Description,,>
-- =============================================
ALTER procedure [dbo].[test]

AS
declare @sysdate int,@flag int
begin
	select @flag = 1 from test where name = 'john'
	if(@flag <> 1)
	begin
		print '!=1'
		print @flag
	end
	else
	begin
		print '=1'
		print @flag
	end
end

这个代码是我后面的简单测试坑的代码,正式的代码不合适贴出来,你懂得!!!这段存储过程的意思就是说在test表中查询name字段,如果存在返回1,执行else语句,不存在则是空,执行if语句,逻辑怎么说似乎都可以说过去,但是我们看一下结果。

=1
1

很明显执行的else中的语句,不管我们查询的结果存在或者不存在,得到的结果都是执行else的内容,只不过不同在于打印出的flag值是不是空罢了。


百思不得其姐之后,尝试使用另外一种方法去测试一下。
看代码;

USE [test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date,,>
-- Description:	<Description,,>
-- =============================================
ALTER procedure [dbo].[test]

AS
declare @sysdate int,@flag int

set @flag=null
begin
	if(@flag = null)
	begin
		print '=null'
		print @flag
	end
	else
	begin
		print 'else'
		print @flag
	end
end

结果:

else

通过上面的测试,我们知道,对于空值来说,是不可以进行比较的,也最好不要用空值进行比较。


正确的写法:

USE [test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date,,>
-- Description:	<Description,,>
-- =============================================
ALTER procedure [dbo].[test]

AS
declare @sysdate int,@flag int

begin
	select @flag = 1 from test where name = 'john'
	if(@flag = 1)
	begin
		print 'OK'
		print @flag
	end
	else
	begin
		print 'else'
		print @flag
	end
end

结果

OK
1

三、总结

在我们写程序的时候,最好使用得到的那个值来使用,比如刚才的用1来判断,我们最好用if判真,也就是分等于1用if判断,其他用else,这样的话,会少踩一点坑。