项目使用的是SQL Server数据库,需要做一个审核规则,字段A中表达式的值和字段B中的值,做比较:

需求本身很简单,但是表达式中存在很多非法字符(非法全角,运算符,汉字……)

eg:1.1.1*2;1*+2,……

因此需要判断,否则直接运算,会报异常

具体SQL如下:

ALTER FUNCTION [dbo].[getNumByExpressions]( @Number nvarchar(500))
RETURNS numeric(10,4)
--返回-1,表示字符串存在问题
--else返回其计算结果
AS
begin
declare @retrunNum numeric(10,4)
declare @NumberStar nvarchar(500)
declare @a numeric(10,4)
declare @b numeric(10,4)

declare @a1 nvarchar(500)
declare @b1 nvarchar(500)

declare @Numberillegal nvarchar(500)
declare @Numberdouble nvarchar(500)

set @retrunNum=0
--判断非法字符
if PATINDEX('%[^0123456789+*.]%', @Number)>0
begin
return -1
end
--判断2个运算符相连接
else if CHARINDEX('..',@Number)>0 or CHARINDEX('**',@Number)>0 or CHARINDEX('++',@Number)>0 or
CHARINDEX('*.',@Number)>0 or CHARINDEX('.*',@Number)>0 or CHARINDEX('+.',@Number)>0 or
CHARINDEX('.+',@Number)>0 or CHARINDEX('*+',@Number)>0 or CHARINDEX('+*',@Number)>0 or rtrim(ltrim(@Number))=''
begin
return -1
end
--判断运算是否在开头和结尾
else if left(@Number,1)='.' or left(@Number,1)='*' or left(@Number,1)='+' or
right(@Number,1)='.' or right(@Number,1)='*' or right(@Number,1)='+'
begin
return -1
end
else
begin
--数字全角判断
set @Numberdouble=@Number
while isnull(len(@Numberdouble),0)>0
begin
if ascii(left(@Numberdouble,1))=163
begin
return -1
end
if len(@Numberdouble)>1
begin
set @Numberdouble = right(@Numberdouble,len(@Numberdouble)-1)
end
else
begin
set @Numberdouble=null
end

end
--计算结果
while CHARINDEX('+',@Number)>0
begin
set @NumberStar = SUBSTRING(@Number,0,CHARINDEX('+',@Number))
set @Number=SUBSTRING(@Number,CHARINDEX('+',@Number)+1,len(@Number)-CHARINDEX('+',@Number))
if CHARINDEX('*',@NumberStar)>0
begin
--判断a,b是否合法:844.5.5*1
set @a1=SUBSTRING(@NumberStar,0,CHARINDEX('*',@NumberStar))
set @b1=SUBSTRING(@NumberStar,CHARINDEX('*',@NumberStar)+1,len(@NumberStar)-CHARINDEX('*',@NumberStar))

if CHARINDEX('.',@a1)>0
begin
set @a1=SUBSTRING(@a1,CHARINDEX('.',@a1)+1,len(@a1)-CHARINDEX('.',@a1))
if CHARINDEX('.',@a1)>0
begin
return -1
end
end
if CHARINDEX('.',@b1)>0
begin
set @b1=SUBSTRING(@b1,CHARINDEX('.',@b1)+1,len(@b1)-CHARINDEX('.',@b1))
if CHARINDEX('.',@b1)>0
begin
return -1
end
end
set @a=SUBSTRING(@NumberStar,0,CHARINDEX('*',@NumberStar))
set @b=SUBSTRING(@NumberStar,CHARINDEX('*',@NumberStar)+1,len(@NumberStar)-CHARINDEX('*',@NumberStar))
set @retrunNum=@retrunNum+@a*@b
end
else
begin
--判断a,b是否合法:844.5.5*1
set @a1=@NumberStar
if CHARINDEX('.',@a1)>0
begin
set @a1=SUBSTRING(@a1,CHARINDEX('.',@a1)+1,len(@a1)-CHARINDEX('.',@a1))
if CHARINDEX('.',@a1)>0
begin
return -1
end
end
set @retrunNum=@retrunNum+@NumberStar
end
end
if CHARINDEX('*',@Number)>0
begin
set @a1=SUBSTRING(@Number,0,CHARINDEX('*',@Number))
set @b1=SUBSTRING(@Number,CHARINDEX('*',@Number)+1,len(@Number)-CHARINDEX('*',@Number))
--判断a,b是否合法:844.5.5*1
if CHARINDEX('.',@a1)>0
begin
set @a1=SUBSTRING(@a1,CHARINDEX('.',@a1)+1,len(@a1)-CHARINDEX('.',@a1))
if CHARINDEX('.',@a1)>0
begin
return -1
end
end
if CHARINDEX('.',@b1)>0
begin
set @b1=SUBSTRING(@b1,CHARINDEX('.',@b1)+1,len(@b1)-CHARINDEX('.',@b1))
if CHARINDEX('.',@b1)>0
begin
return -1
end
end
set @a=SUBSTRING(@Number,0,CHARINDEX('*',@Number))
set @b=SUBSTRING(@Number,CHARINDEX('*',@Number)+1,len(@Number)-CHARINDEX('*',@Number))
set @retrunNum=@retrunNum+@a*@b
end
else
begin
--判断a,b是否合法:844.5.5*1
set @a1=@Number
if CHARINDEX('.',@a1)>0
begin
set @a1=SUBSTRING(@a1,CHARINDEX('.',@a1)+1,len(@a1)-CHARINDEX('.',@a1))
if CHARINDEX('.',@a1)>0
begin
return -1
end
end
set @retrunNum=@retrunNum+@Number
end
end
return @retrunNum
end

SQL Server中计算表达式的和的更多相关文章

  1. SQL Server 中计算农历

    1.建一表,放初始化资料   因为农历的日期,是由天文学家推算出来的,到现在只有到2049年的,以后的有了还可以加入!   CREATE TABLE SolarData ( yearId int no ...

  2. 使用CASE表达式替代SQL Server中的动态SQL

    原文:使用CASE表达式替代SQL Server中的动态SQL 翻译自: http://www.mssqltips.com/sqlservertip/1455/using-the-case-expre ...

  3. 此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行

    错误提示:此操作只能由 SQL Server 中拥有配置数据库读取权限的用户在已加入到某个服务器场的计算机上执行.若要将此服务器连接到服务器场,请使用 SharePoint 产品配置向导,该向导可从 ...

  4. sql server中的临时表、表变量和公用表表达式

    在编写T-SQL语句的时候,SQL Server提供了三种方法临时存储某些结果集,分别是临时表.表变量和公用表表达式. 临时表 临时表需要在临时数据库TempDB中通过I/O操作来创建表结构,一旦用户 ...

  5. SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题

    用户定义函数(UDF)分类  SQL SERVER中的用户定义函数(User Defined Functions 简称UDF)分为标量函数(Scalar-Valued Function)和表值函数(T ...

  6. Sql Server中不常用的表运算符之APPLY(2)

    在Sql Server中不常用的表运算符之APPLY(1)中提到,SQL2005中新支持的APPLY的特性:1.可以直接将表表达式(表值函数或者子查询)作为APPLY语句的右表连接左表.2.由于使用A ...

  7. SQL Server中的RAND函数的介绍和区间随机数值函数的实现

        工作中会遇到SQL Server模拟数据生成以及数值列值(如整型.日期和时间数据类型)随机填充等等任务,这些任务中都要使用到随机数.鉴于此,本文将对SQL Server中随机数的使用简单做个总 ...

  8. SQL Server中的SQL语句优化与效率问题

    很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解.比如: select * from table1 where name='zhan ...

  9. SQL SERVER中的流程控制语句

    流程控制语句 是指用来控制程序运行和流程分至点额命令.一般指的是逻辑计算部分的控制. 1.Begin End语句 封装了多个T-SQL语句组合,将他们组成一个单元来处理. 一般在条件查询或者循环等控制 ...

随机推荐

  1. flexbox 弹性盒子

    flexbox 弹性盒子 1.基本知识 container(容器)属性 flex-direction: row | row-reverse | column | column-reverse 属性决定 ...

  2. hdu_1030(数学题+找规律)

    规律就是两个数字的level差+left差+right差 代码: #include<cstdio> #include<iostream> #include<cstring ...

  3. Linux使用Public Key方式远程登录

    一.前言: ssh远程登录密码认证的方式有三种,password.Keyboard Interactive.Public Key 前面两种方式就是密码认证,含义都是一样大同小异.第三种是登录方式最安全 ...

  4. Flexbox 练习和总结

    练习地址: http://flexboxfroggy.com/ Welcome to Flexbox Froggy, a game where you help Froggy and friends ...

  5. TCP层的分段和IP层的分片之间的关系 & MTU和MSS之间的关系 (转载)

    首先说明:数据报的分段和分片确实发生,分段发生在传输层,分片发生在网络层.但是对于分段来说,这是经常发生在UDP传输层协议上的情况,对于传输层使用TCP协议的通道来说,这种事情很少发生. 1,MTU( ...

  6. 科普:String hashCode 方法为什么选择数字31作为乘子

    1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主 ...

  7. [基础常识]申请免费SSL证书 - 阿里云云盾证书 - Digicert+Symantec 免费型DV SSL

    https://bbs.aliyun.com/read/573933.html?spm=5176.10695662.1996646101.searchclickresult.72be06dct9Qvw ...

  8. 常用sql语句整理:mysql

    ## 常用sql语句整理:mysql1. 增- 增加一张表```CREATE TABLE `table_name`(  ...  )ENGINE=InnoDB DEFAULT CHARSET=utf8 ...

  9. MySQL查询性能优化一则

    公司有一套Web系统, 使用方反馈系统某些页面访问速度缓慢, 用户体验很差, 并且偶尔还会出现HTTP 502错误. 这是典型的服务器端IO阻塞引发的问题,通过对访问页面的程序逻辑进行跟踪,发现问题应 ...

  10. django 编程小结

    1.增删改查 add obj = Obj(atr=atr..) obj.save() update: __dict__ 遍历 del: 根据id列表删除 query: 首次查询: 直接跳转至页面,前端 ...