【发布时间】:2016-06-17 14:14:20
【问题描述】:
我有一个存储过程,我正在尝试使用它来提高它的效率。不幸的是,它目前可能被许多应用程序使用,所以尽管我的最佳解决方案是重写它,但我目前受到那里的限制。
最初有两个输入参数,都是 VARCHAR。我需要根据第一个参数的值将两者与不同的数据类型进行比较。但是,当它们不应该存在时,我会遇到转换错误。示例:
PROCEDURE ProcedureName
@SearchType VARCHAR(24)
, @SearchID VARCHAR(100)
AS
BEGIN
SELECT
t1.*,
t2.*
FROM
TableOne t1
JOIN TableTwo t2
WHERE
(CASE
WHEN UPPER(@SearchType) = 'GUID' THEN CAST(t2.guid AS VARCHAR(100))
WHEN UPPER(@SearchType) = 'ID' THEN t2.id
WHEN UPPER(@SearchType) = 'ANOTHERID' THEN t1.id
END)
=
(CASE
WHEN UPPER(@SearchType) = 'GUID' THEN @SearchID
WHEN UPPER(@SearchType) = 'ID'
OR UPPER(@SearchType) ='ANOTHERID' THEN CAST(@SearchID AS INT)
END)
END
这里的目标是如果 Search 类型是 GUID,它将转换表中的 guid 列并与输入字符串进行比较。 由于数据库中的两个 ID 字段都是 int 类型的列,我想将 SearchID(当传入 ID 或 ANOTHERID 时将具有整数的基础数据类型)转换为整数类型以匹配本机列类型。 但是,每次我尝试使用@SearchType 中的“GUID”和@SearchID 中的 guid 运行它时,都会收到此错误: 将 varchar 值“”转换为数据类型 int 时转换失败。
这个 case 语句不应该是短路的,所以这个输入不应该转换为 int 吗?可以强制短路吗?
【问题讨论】:
-
从
where子句中删除所有计算和转换,声明三个适当类型的变量,在select语句之前分配它们并使用准备比较where中的变量。并输入option(recompile),因为存储的计划不会在下次运行时让您感到舒适。 -
我在过程中添加了以下内容:
IF UPPER(@SearchType) = 'ID' OR UPPER(@SearchType) ='ANOTHERID' BEGIN SET @IntSearchID = CAST(@SearchID AS INT) END然后我在最后只使用一个新变量进行比较,因为输入变量已经是一个 varchar,其他两个选项是both int: WHEN UPPER(@SearchType) = 'ID' OR UPPER(@SearchType) ='ANOTHERID' THEN @IntSearchID 但是,我仍然收到转换错误。
标签: sql-server case short-circuiting