Sql server 如何在Case语句中显示@Var结果,并在@Var版本2之前和之后显示文本

Sql server 如何在Case语句中显示@Var结果,并在@Var版本2之前和之后显示文本,sql-server,variables,sql-server-2012,case,Sql Server,Variables,Sql Server 2012,Case,我的问题是: DECLARE @RecordCount as INT DECLARE @today as VARCHAR(10) SET @today = convert(varchar(10),getdate(),120) Set @RecordCount = (Select COUNT(*) FROM tableABC select case when @RecordCount = 0 THEN 'There was no data found for tableABC

我的问题是:

 DECLARE @RecordCount as INT
 DECLARE @today as VARCHAR(10)

 SET @today = convert(varchar(10),getdate(),120)
  Set @RecordCount = (Select COUNT(*)
 FROM tableABC

 select case when @RecordCount = 0
  THEN 'There was no data found for tableABC: ' + @Today 
  ELSE 'tableABC imported ' + @RecordCount +' rows for date range ' + @Today
  END
错误消息

转换时,Msg 245,16级,状态1,第8行转换失败 varchar值“tableABC imported”为数据类型int


为什么会出现此错误?

SQL Server尝试将字符串转换为int,原因是:

当运算符组合两个不同数据类型的表达式时 数据类型优先级规则指定具有 较低优先级转换为具有较高优先级的数据类型 优先权如果转换不是受支持的隐式转换, 返回一个错误

INT
在前缀列表中是16,字符串常量(
VARCHAR
)更低。因此,SQL Server尝试将每个字符串强制转换为
INT

将记录计数转换为字符串:

select 
   case when @RecordCount = 0
     THEN 'There was no data found for tableABC: ' + @Today 
     ELSE 'tableABC imported ' + CAST(@RecordCount AS NVARCHAR(100)) +' rows for date range ' + @Today
   end

您也应该考虑使用<强> 字符串连接,而不是<代码> +<代码>。那么你就不需要投:

select 
   case when @RecordCount = 0
     THEN CONCAT('There was no data found for tableABC: ',@Today)
     ELSE CONCAT('tableABC imported ', @RecordCount,' rows for date range ', @Today)
   end
另一种解决方案是使用

DECLARE @RecordCount as INT = 1;
DECLARE @today as VARCHAR(10) = convert(varchar(10),getdate(),120);

SELECT
  CASE 
   WHEN @RecordCount = 0 THEN FORMATMESSAGE('There was no data found for tableABC: %i', @RecordCount)
   ELSE FORMATMESSAGE('tableABC imported %i rows for date range %s', @RecordCount, @today)
  END

问题是,当您将内容组合到一个字符串中时,该字符串的所有元素都需要是基于文本而不是数字的数据类型。由于您之前使用@RecordCount作为整数,最好是在else语句中将其强制转换为varchar。varchar和int之间存在隐式转换,但SQL server出于超出我理解的原因,选择始终尝试将文本转换为int,而不是相反的方式。因此,tex可以;t convert,因此您会收到错误消息。

错误消息包含解决问题所需的所有内容。@recordCount是一个int-您需要强制转换它。您正在尝试将
VARCHAR
字符串('tableABC imported')与一个整数(
Select COUNT(*)from table ABC
)连接在一起(
“varchar和int之间存在隐式转换,但SQL server之间存在隐式转换,其原因超出了我的理解“
有一个简单的解决方案:)我知道先例,但我不明白先例背后的原因这对于最广泛到最狭隘的先例来说是相当清楚的。但由于varchar优先于int更有意义,我仍然不明白。((大多数情况下,当您需要这种隐式转换时,需要将int转换为varchars,而不是相反。)他们这样做的方式保证了更多的错误而不是更少。这是相同的逻辑,就像
每个正方形都是矩形,但不是每个矩形都是正方形。
。SQL Server始终可以将INT强制转换为varchar,但不能将INT强制转换为varcharversa@RickyTW请参阅我的CONCAT更新答案/FORMATMESSAGE@RickyTW如果它对你有帮助,请考虑标记为答案:
select case when @RecordCount = 0
  THEN 'There was no data found for tableABC: ' + @Today 
  ELSE 'tableABC imported ' + cast(@RecordCount as varchar(10)) +' rows for date range ' + @Today
  END