我在从VBA执行存储过程时遇到了一个问题:我想传入一个列名作为参数的字符串,然后使用case语句在数据中选择实际的列名
当通过的列名(@FACTOR)是一个整数时,此查询可以正常工作,但当它是一个varchar时则不行。我收到转换错误:
将数据类型nvarchar转换为float时出错。
这是我的代码:
WITH T0 AS (
SELECT DISTINCT
CASE @FACTOR
WHEN 'DRVREC' THEN DRIVINGRECORD --OK
WHEN 'POAGE' THEN POAGE
WHEN 'ANNUALKM' THEN AMC_VH_ANNL_KM
WHEN 'DAILYKM' THEN AMC_VH_KM_TO_WRK
WHEN 'RATETERR' THEN AMC_VH_RATE_TERR --OK
WHEN 'BROKERNAME' THEN MASTERBROKER_NAME
WHEN 'DRVCLASS' THEN DRIVINGCLASS -- OK
WHEN 'VEHAGE' THEN VEH_AGE -- OK
WHEN 'YEARSLIC' THEN YRSLICENSE
WHEN 'COVERAGECODE' THEN COVERAGECODE
ELSE NULL END AS FACTOR FROM DBO.Automation_Data
),
...
...
或许以下示例更简洁:
DECLARE @FACTOR varchar(50)
SELECT @FACTOR = 'NOT_A_VARCHAR'
SELECT CASE @FACTOR
WHEN 'A_VARCHAR' THEN COLUMNNAME1
WHEN 'NOT_A_VARCHAR' THEN COLUMNNAME2
ELSE NULL END AS FACTOR FROM dbo.myTable
^这会有效,但是如果@FACTOR = 'A_VARCHAR'
那么我就会收到错误。
提前致谢!
更新**********************************:
案件陈述本身似乎是一个问题?
当我在case语句中只有varchar选项时,查询会运行。当我取消评论案例陈述的第二部分时,我得到了错误。
DECLARE @FACTOR varchar(50)
SELECT @FACTOR = 'A_VARCHAR'
SELECT CASE @FACTOR
WHEN 'A_VARCHAR' THEN COLUMNNAME1
--WHEN 'NOT_A_VARCHAR' THEN COLUMNNAME2 ELSE NULL
END AS FACTOR FROM dbo.myTable
答案 0 :(得分:1)
当您从多个列中选择单个列时,SQL会将结果作为最高优先级类型返回。当从多种数据类型返回单个结果时,与合并等相同。
如果你尝试下面的代码,例如,3rd select将返回你得到的错误,因为它试图将abc
转换为int(更高的优先级)。如果将@V设置为'123'
,则错误将消失,因为从'123'
到int / float的转换有效。检查结果的'BaseType'
时,可以看到它显示混合类型的最高优先级数据类型。
DECLARE @F int = 1 --if you use float here error message will show ...'abc' to data type float.
DECLARE @V varchar(5) = 'abc'
DECLARE @O varchar = '1'
SELECT CASE WHEN @O = '1' THEN @F ELSE @V END --no error
SELECT SQL_VARIANT_PROPERTY((SELECT CASE WHEN @O = '1' THEN @F ELSE @V END), 'BaseType') --int/float
SET @O = '2'
SELECT CASE WHEN @O = '1' THEN @F ELSE @V END --error: Conversion failed when converting the varchar value 'abc' to data type int.
当您将所有选择转换为nvarchar时,nvarchar成为最高优先级数据类型,因此它起作用。但是如果你知道你的一些列是float并且其中一些是nvarchar,你只需要将float列转换为nvarchar。所以这也会起作用:
SET @O = '2'
SELECT CASE WHEN @O = '1' THEN CONVERT(NVARCHAR(5), @F) ELSE @V END