SELECT 中的 SMALLINT 到 VARCHAR 的转换/SQL 查询中的 CASE 语句

SMALLINT to VARCHAR conversion in SELECT / CASE statement in SQL query

我正在编写一个代码,该代码采用十进制输出并将其更改为缩写的十六进制输出。但是,当我尝试将 smallint 格式转换为 varchar 时收到一条错误消息。当我 运行 下面的代码时,我收到错误消息

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'E' to data type smallint

我尝试将 SELECT 语句转换为:

SELECT 
    *, 
    CONVERT(VARCHAR, PCM_ID1)

但是这个returns同样的错误信息。我还将代码修改为

...
WHEN PCM_ID1 = '10' THEN CAST('A' AS VARCHAR)
WHEN PCM_ID1 = '11' THEN CAST('B' AS VARCHAR)
WHEN PCM_ID1 = '12' THEN CAST('C' AS VARCHAR)
WHEN PCM_ID1 = '13' THEN CAST('D' AS VARCHAR)
WHEN PCM_ID1 = '14' THEN CAST('E' AS VARCHAR)
WHEN PCM_ID1 = '15' THEN CAST('F' AS VARCHAR)
...

这也是 returns 相同的错误消息。原始代码示例如下:

SELECT 
    *, 
FROM
    dbo.DMV_All_Tests
CROSS APPLY 
    (SELECT
         CASE
            WHEN PCM_ID1 = '0' THEN '0'
            WHEN PCM_ID1 = '1' THEN '1'
            WHEN PCM_ID1 = '2' THEN '2'
            WHEN PCM_ID1 = '3' THEN '3'
            WHEN PCM_ID1 = '4' THEN '4'
            WHEN PCM_ID1 = '5' THEN '5'
            WHEN PCM_ID1 = '6' THEN '6'
            WHEN PCM_ID1 = '7' THEN '7'
            WHEN PCM_ID1 = '8' THEN '8'
            WHEN PCM_ID1 = '9' THEN '9'
            WHEN PCM_ID1 = '10' THEN 'A'
            WHEN PCM_ID1 = '11' THEN 'B' 
            WHEN PCM_ID1 = '12' THEN 'C'
            WHEN PCM_ID1 = '13' THEN 'D'
            WHEN PCM_ID1 = '14' THEN 'E'
            WHEN PCM_ID1 = '15' THEN 'F'
            WHEN PCM_ID1 = '16' THEN '10'
            ELSE PCM_ID1
         END AS [PCM ID1 Dec2Hex]) ca
WHERE
    KeyDateTime BETWEEN '2018/11/01' AND '2018/12/01' 
    AND ca.[PCM ID1 Dec2Hex] = '1'

我的目标是完成一次成功的转换,这样就不会像 PCM_ID1 那样在数据库中存储“14”,它会给我等效的十六进制值,如 'F' 或 ' 0F'。这将用于与我们的其他数据库进行交叉检查,该数据库将这些 PCM_ID1 值存储为十六进制。

所以我重现了你的错误:

DECLARE @X TABLE (PCM_ID1 smallint)

INSERT INTO @X SELECT 14
INSERT INTO @X SELECT 1

    SELECT
    CASE
        WHEN PCM_ID1 = '0' THEN '0'
        WHEN PCM_ID1 = '1' THEN '1'
        WHEN PCM_ID1 = '2' THEN '2'
        WHEN PCM_ID1 = '3' THEN '3'
        WHEN PCM_ID1 = '4' THEN '4'
        WHEN PCM_ID1 = '5' THEN '5'
        WHEN PCM_ID1 = '6' THEN '6'
        WHEN PCM_ID1 = '7' THEN '7'
        WHEN PCM_ID1 = '8' THEN '8'
        WHEN PCM_ID1 = '9' THEN '9'
        WHEN PCM_ID1 = '10' THEN 'A'
        WHEN PCM_ID1 = '11' THEN 'B' 
        WHEN PCM_ID1 = '12' THEN 'C'
        WHEN PCM_ID1 = '13' THEN 'D'
        WHEN PCM_ID1 = '14' THEN 'E'
        WHEN PCM_ID1 = '15' THEN 'F'
        WHEN PCM_ID1 = '16' THEN '10'
        ELSE PCM_ID1
    END AS [PCM ID1 Dec2Hex]
    FROM @X

如果你这样做,你会得到同样的错误。原因是因为你的 case 语句中的 ELSE returns 是一个 smallint 字段,它使字段 [PCM ID1 Dec2Hex] smallint 并且你得到了错误。

如果您将 else 转换为 varchar,它将解决此问题。问题是它试图将 E 转换回 smallint。我希望这是有道理的。

DECLARE @X TABLE (PCM_ID1 smallint)

INSERT INTO @X SELECT 14
INSERT INTO @X SELECT 1

    SELECT
    CASE
        WHEN PCM_ID1 = '0' THEN '0'
        WHEN PCM_ID1 = '1' THEN '1'
        WHEN PCM_ID1 = '2' THEN '2'
        WHEN PCM_ID1 = '3' THEN '3'
        WHEN PCM_ID1 = '4' THEN '4'
        WHEN PCM_ID1 = '5' THEN '5'
        WHEN PCM_ID1 = '6' THEN '6'
        WHEN PCM_ID1 = '7' THEN '7'
        WHEN PCM_ID1 = '8' THEN '8'
        WHEN PCM_ID1 = '9' THEN '9'
        WHEN PCM_ID1 = '10' THEN 'A'
        WHEN PCM_ID1 = '11' THEN 'B' 
        WHEN PCM_ID1 = '12' THEN 'C'
        WHEN PCM_ID1 = '13' THEN 'D'
        WHEN PCM_ID1 = '14' THEN 'E'
        WHEN PCM_ID1 = '15' THEN 'F'
        WHEN PCM_ID1 = '16' THEN '10'
        ELSE CAST(PCM_ID1 AS VARCHAR)
    END AS [PCM ID1 Dec2Hex]
    FROM @X
declare @input as smallint = 1;
select format(@input, 'X');