首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Server 2017评估了一段不应该计算的代码

Server 2017评估了一段不应该计算的代码
EN

Stack Overflow用户
提问于 2020-08-03 05:30:20
回答 3查看 54关注 0票数 0
代码语言:javascript
运行
复制
select * 
from fb_lab_test 
where (report_item_code = 'HBcAb') 
   or (report_item_code = 'Anti-Hbc' and 
       case isnumeric(result) when 1 then cast(result as float) else 10000.0 end > 0.2)

将数据类型varchar转换为浮动的

错误

这是样本数据

代码语言:javascript
运行
复制
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE fb_lab_test
(
    [id] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    [Test_No] [varchar](50) NULL,
    [execute_date] [datetime] NULL,
    [PatientId] [varchar](20) NULL,
    [Visit_Id] [varchar](10) NULL,
    [Patient_Type] [int] NULL,
    [PatientName] [varchar](100) NULL,
    [result_date_time] [datetime] NULL,
    [report_item_name] [varchar](256) NULL,
    [report_item_code] [varchar](50) NULL,
    [result] [varchar](100) NULL
) ON [PRIMARY]
GO

INSERT INTO fb_lab_test 
VALUES ('5910315197','2019-10-31 00:40:53.000','111111','1','1','Tom','2019-10-31 08:56:54.000','test1','KET','-')

在这个示例数据中,isnumeric将返回假阳性,但是不应该对case isnumeric(result) when 1 then cast(result as float) else 10000.0 end > 0.2进行评估,因为在示例日期中没有名为‘Anti’的report_item_code,这很奇怪。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-08-03 05:39:05

在我的情况下(使用您的数据),不会引发错误。有时,引擎决定提前执行操作(以便优化特定的查询)。我相信,你因为这种行为而犯了错误。

您可以使用TRY_CAST修复它

代码语言:javascript
运行
复制
select * from fb_lab_test 
where (report_item_code = 'HBcAb') 
or (
    report_item_code = 'Anti-Hbc' and 
    case isnumeric(result) when 1 then try_cast(result as float) else 10000.0 end > 0.2
)
票数 1
EN

Stack Overflow用户

发布于 2020-08-03 05:59:55

它实际上是根据文件行事..。

ISNUMERIC为一些非数字字符返回1,例如加号(+)、减号(-)和有效的货币符号(如美元符号($) )。有关货币符号的完整列表,请参见货币和小额货币(Transact-SQL)。

https://learn.microsoft.com/en-us/sql/t-sql/functions/isnumeric-transact-sql?view=sql-server-ver15

当将非数值字符、nchar、nvarchar或varchar数据转换为十进制、浮点数、int值、数字值时,Server返回错误消息。当空字符串(“")转换为数字或十进制时,Server还会返回一个错误。

https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver15

如果您需要在一个表达式中转换它,我建议您使用支持4位小数位的货币类型。否则,您必须处理+-.等的“可能”数字值.

票数 0
EN

Stack Overflow用户

发布于 2020-08-03 11:47:06

根本不要使用isnumeric()。只需使用try_函数:

代码语言:javascript
运行
复制
select t.* 
from fb_lab_test t
where report_item_code = 'HBcAb'  or
      (report_item_code = 'Anti-Hbc' and 
       coalesce(try_cast(float_result), 10000.0) > 0.2
      );

避免在case子句中使用where表达式也是一个好主意。他们基本上是短路优化器。

在本例中,您希望包含非数字值。更常见的是,这将被排除在外。您可以让NULL比较排除它们。这种逻辑是:

代码语言:javascript
运行
复制
select t.* 
from fb_lab_test t
where report_item_code = 'HBcAb'  or
      (report_item_code = 'Anti-Hbc' and 
       try_cast(float_result) > 0.2   -- excludes non-NULL values
      );
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63224190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档