Sql 在CASE语句中使用CAST时发生数据转换错误

Sql 在CASE语句中使用CAST时发生数据转换错误,sql,sql-server,tsql,sql-server-2008,Sql,Sql Server,Tsql,Sql Server 2008,运行以下命令时,我收到错误“将数据类型nvarchar转换为float时出错” declare @completeCommand nvarchar (max) = 'x' ,@paramVal nvarchar (100) ,@paramName nvarchar (100) ,@paramType nvarchar (100) ,@tempParam

运行以下命令时,我收到错误“将数据类型nvarchar转换为float时出错”

     declare 
     @completeCommand       nvarchar (max) = 'x'
    ,@paramVal              nvarchar (100)
    ,@paramName             nvarchar (100)
    ,@paramType             nvarchar (100)
    ,@tempParam             sql_variant

  declare @parameterList table (
      RowID           int identity (1,1)
     ,ParameterValue  nvarchar (100)
     ,ParameterName   nvarchar (100)
     ,ParameterType   nvarchar (100)
  )

  insert into @parameterList
  values
     ('10', 'Param1', 'int')
    ,('test', 'Param2', 'nvarchar')

  -- Process each parameter one at a time
  declare ParameterCursor cursor fast_forward for
    select ParameterValue, ParameterName, ParameterType
    from @parameterList
    order by RowID

  open ParameterCursor

  fetch next from ParameterCursor into @paramVal, @paramName, @paramType

  if @@FETCH_STATUS = 0
    set @completeCommand = @completeCommand + ' '

  while @@FETCH_STATUS = 0
  begin

    print @completeCommand

    -- verify the datatype is correct
    set @tempParam = case @paramType
          when 'int' then CAST (@paramVal as int)
          when 'float' then CAST (@paramVal as float)
          when 'nvarchar' then CAST (@paramVal as nvarchar)
          else 'NULL'
        end 

    set @completeCommand = @completeCommand + @paramName + ' = ' + @paramVal + ','

    fetch next from ParameterCursor into @paramVal, @paramName, @paramType
  end

  close ParameterCurosr
  deallocate ParameterCursor
我试图做的是在将数据添加到命令字符串之前验证用户输入的数据是否与预期的数据类型匹配。任何关于上述代码失败原因的反馈都将不胜感激

干杯,
Joe

问题在于,CASE将返回具有最高精度的数据类型,其中该语句的精度为float。见和

若要使此案例正常工作,请在“xzy”时添加一个伪值,然后将@paramVal强制转换为sql_variant,这将导致案例使用sql_variant作为返回数据类型

或者移除机箱并使用IF-ELSE,如:


您使用的是简单的Case函数。搜索的案例功能应能正常工作,请参见下文。 我刚刚在一个非常简单的查询中尝试过:

DECLARE @type VARCHAR(100)
DECLARE @input VARCHAR(100)
DECLARE @value SQL_VARIANT

SET @type = 'varchar'
SET @input = 'test'

SET @value = CASE 
   WHEN @type = 'varchar' THEN @input
   WHEN @type = 'int' THEN CAST(@input AS VARCHAR)
END
在SQL Server 2005上,我收到了相同的错误,但以下错误来自SQL Server 2008文档:

简单案例功能:

对输入表达式求值,然后按照指定的顺序对每个when子句的输入表达式=when表达式求值。 返回计算结果为TRUE的第一个输入表达式的结果表达式。 如果no input_expression=当_expression的计算结果为TRUE时,如果指定了else子句,SQL Server 2005数据库引擎将返回else_result_表达式;如果未指定else子句,则返回NULL值。 搜索案例功能:

按照指定的顺序计算每个WHEN子句的布尔_表达式。 返回计算结果为TRUE的第一个布尔\u表达式的结果\u表达式。 如果没有布尔_表达式的计算结果为TRUE,则如果指定了else子句,则数据库引擎将返回else_result_表达式;如果未指定else子句,则返回NULL值。 如果这是真的,那么Simple Case将执行所有转换,然后决定使用哪个,而Searched Case将计算布尔表达式,然后决定执行哪个转换。这应该是解决办法


否则,如果。。。然后否则,正如另一个答案中所建议的。

基本缺陷-您依赖用户输入的数据类型。仅仅因为我将数据标记为NVARCHAR,并不意味着它就是。您应该考虑在转换之前使用ISDigic来确认数值数据类型。但这并不能解释为什么case语句没有选择正确的WHEN子句。小心,ISNUMERIC不是IsAllDigits函数。看一看这篇文章免费注册到站点所需:@OMG Ponies,ISNUMERIC是一个开始,但如果它是用户输入和转换为浮点之间的唯一防线,您仍然会有错误。ISNUMERIC不会捕获许多基本问题,请尝试选择ISNUMERIC“$1”、ISNUMERIC“1234.0”、ISNUMERIC“12e4”。所有这些都报告为数字,但当您将它们转换为float/numeric/etc时将失败。您引用的文档与我所引用的相同,只是您引用了案例如何确定何时使用,而不是返回的数据类型。在文档中,转到Simple CASE函数标题之前,请参阅从result_表达式中的类型集和可选的else_result_表达式中返回优先级最高的类型。这是关键:返回的数据类型,如果案例决定按此处的方式返回浮点,如果您尝试返回字符串,则会出现转换错误。继续。。。正如我的回答所说,修改大小写,使sql_variant是返回的类型,它的优先级高于float,或者只使用IF-ELSEI see。。。现在我想我在这里呆着太累了,回答问题而不理解我读的东西。你最好听从KM的建议@KM:谢谢你指出这一点,而不是打我的脸,因为今晚我可能活该。。。
DECLARE @type VARCHAR(100)
DECLARE @input VARCHAR(100)
DECLARE @value SQL_VARIANT

SET @type = 'varchar'
SET @input = 'test'

SET @value = CASE 
   WHEN @type = 'varchar' THEN @input
   WHEN @type = 'int' THEN CAST(@input AS VARCHAR)
END