【问题标题】:Why does this query fail with "Cannot convert a char value to money. "为什么此查询失败并显示“无法将 char 值转换为货币。”
【发布时间】:2022-01-17 22:39:24
【问题描述】:

附录:我不知道为什么它的票数接近,因为“结果不可重复”。提供了模式和数据脚本,并提供了相关脚本。都在那里。

此查询失败:

SELECT 
    P.Profession AS Profession,
    CASE
        WHEN P.AverageAnnualSalary >= 200000
            THEN 'wow'
        WHEN P.AverageAnnualSalary >= 100000 
             AND P.AverageAnnualSalary <= 199999
            THEN 'nice'
        WHEN P.AverageAnnualSalary >= 0 
             AND P.AverageAnnualSalary <= 99999
            THEN 'ok'
        ELSE P.AverageAnnualSalary
    END AS Description
FROM
    tProfession2 AS P
ORDER BY 
    Profession ASC

出现此错误:

消息 235,第 16 级,状态 0,第 1 行
无法将 char 值转换为货币。 char 值的语法不正确。

此查询有效:

SELECT Profession AS Profession,
       CASE 
           WHEN P.AverageAnnualSalary >= 200000 THEN 'wow'
           WHEN P.AverageAnnualSalary >= 100000 THEN 'nice'
           ELSE 'ok'
        END AS Description
FROM tProfession2 P
ORDER BY Profession ASC

这是架构和数据:

/****** Object:  Table [dbo].[tProfession2]    Script Date: 12/14/2021 10:48:41 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tProfession2](
    [ProfessionID] [int] IDENTITY(1,1) NOT NULL,
    [Profession] [nchar](50) NOT NULL,
    [AverageAnnualSalary] [money] NULL,
 CONSTRAINT [PK_tProfession2] PRIMARY KEY CLUSTERED 
(
    [ProfessionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[tProfession2] ON 
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (1, N'Doctor                                            ', 200000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (2, N'Attorney                                          ', 350000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (3, N'Software Engineer                                 ', 120000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (4, N'Cybersecurity Consultant                          ', 110000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (5, N'Network Engineer                                  ', 111000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (6, N'Farmer                                            ', 200000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (7, N'Chef                                              ', 250000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (8, N'Truck Driver                                      ', 99000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (9, N'Wilderness Guide                                  ', 45000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (10, N'HVAC Technician                                   ', 79000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (11, N'Electrician                                       ', 80000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (12, N'TV Personality                                    ', 450000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (13, N'NFL Quarterback                                   ', 2000000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (14, N'Soccer Player                                     ', 4000000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (15, N'Electrical Engineer                               ', 130000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (16, N'Computer Engineer                                 ', 135000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (17, N'Business Owner                                    ', 4500000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (18, N'Politician                                        ', 20000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (19, N'City Manager                                      ', 90000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (20, N'Landscaper                                        ', 80000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (21, N'Pilot                                             ', 200000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (22, N'Insurance Salesperson                             ', 230000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (23, N'Interior Designer                                 ', 55000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (24, N'Architect                                         ', 600000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (25, N'IRS Agent                                         ', 99000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (26, N'Accountant                                        ', 120000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (27, N'Tax Preparer                                      ', 60000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (28, N'Spy                                               ', 0.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (29, N'Military Officer                                  ', 45000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (30, N'Veterinarian                                      ', 300000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (31, N'Roofer                                            ', 67000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (32, N'Arborist                                          ', 76000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (33, N'Painter                                           ', 60000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (34, N'Flight Attendant                                  ', 50000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (35, N'Amish Farmer                                      ', 10000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (36, N'Carpet Installer                                  ', 40000.0000)
GO
INSERT [dbo].[tProfession2] ([ProfessionID], [Profession], [AverageAnnualSalary]) VALUES (37, N'Baker                                             ', 900000.0000)
GO
SET IDENTITY_INSERT [dbo].[tProfession2] OFF
GO
SET ANSI_PADDING ON
GO
/****** Object:  Index [IX_tProfession]    Script Date: 12/14/2021 10:48:42 AM ******/
ALTER TABLE [dbo].[tProfession2] ADD  CONSTRAINT [IX_tProfession2] UNIQUE NONCLUSTERED 
(
    [Profession] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO

【问题讨论】:

  • CASE 表达式返回一个标量值。在上面,您尝试返回 varchar'wow''nice''ok' 或列 P.AverageAnnualSalary。对于后者,我建议包含某人工资的列不是varchar,因此尝试将其他值转换为该列的数据类型(似乎是money)。为什么要在同一列中返回字符串和数字数据?为什么你需要ELSE,因为它很可能永远不会被退回。
  • 这是一个聪明的问题,调试时尝试自然的事情。将薪水输出转换为 varchar,这样所有案例都将具有相同的类型。

标签: sql sql-server


【解决方案1】:

据我所知,您的 ELSE 不应该在那里。对于您拥有的值,只有在 P.AverageAnnualSalary 为负数时才会返回您的 ELSE(不太可能,我假设您没有为您工作的员工),NULL(没有意义然后返回它,还不如省略ELSE),或199999200000之间(例如199999.7)或99999100000之间(例如99999.5)。

您实际上并不需要上限。例如,如果第一个 WHEN 不正确,则该值已经隐式 小于 200000。然后你完全删除ELSE,从而删除隐式转换。

    CASE WHEN P.AverageAnnualSalary >= 200000 THEN 'wow'
         WHEN P.AverageAnnualSalary >= 100000 THEN 'nice'
         WHEN P.AverageAnnualSalary >= 0 THEN 'ok'
    END 

【讨论】:

    【解决方案2】:

    CASE 表达式的结果是一个特定的数据类型。 SQL Server 返回"highest precedence type from the set of types in result_expressions"

    使用data type precedence order,您可以将“ok”和“nice”转换为money

    解决这个问题

    ELSE CAST( P.AverageAnnualSalary AS VARCHAR( 30 ))
    

    【讨论】:

      【解决方案3】:

      问题很简单直接,在 case 语句中,您将返回 else 情况下的字符值 excpet。所以只需将 else 转换为字符串,它就会起作用

      SELECT P.Profession AS Profession,
          CASE
              WHEN P.AverageAnnualSalary >= 200000
                  THEN 'wow'
              WHEN P.AverageAnnualSalary >= 100000 
                   AND P.AverageAnnualSalary <= 199999
                  THEN 'nice'
              WHEN P.AverageAnnualSalary >= 0 
                   AND P.AverageAnnualSalary <= 99999
                  THEN 'ok'
              ELSE CAST(P.AverageAnnualSalary AS VARCHAR(50))
          END AS Description
      FROM tProfession2 AS P
      ORDER BY Profession ASC
      

      【讨论】:

      • 我觉得这不是正确的决定。 “描述”和值应该是不同的列。虽然AverageAnnualSalary 只能在行具有值NULL&lt; 0介于19999920000099999100000 之间返回(例如99999.5)。
      猜你喜欢
      • 1970-01-01
      • 2019-06-05
      • 1970-01-01
      • 2014-01-28
      • 2022-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      相关资源
      最近更新 更多