【问题标题】:GETDATE() Msg 241 Conversion failed when converting date and/or time from character stringGETDATE() Msg 241 从字符串转换日期和/或时间时转换失败
【发布时间】:2018-07-02 08:42:49
【问题描述】:

此 SQL 语句在我的一台服务器上引发转换错误:

DECLARE @TimeStamp datetime;
SET @TimeStamp = GETDATE();

INSERT INTO Lookups 
    SELECT 
        newid() AS Id, 
        'Type' AS Type, Name, 
        'A.Miller' AS CreatedName, 
        'A.Miller' AS ChangedName,
        @TimeStamp AS CreatedDate, 
        @TimeStamp AS ChangedDate 
    FROM 
        [DBServer].[Database].[dbo].[LkValues] 
    WHERE 
        NOT Name IS NULL OR Name = ''

错误:

消息 241,第 16 级,状态 1,第 5 行
从字符串转换日期和/或时间时转换失败。

我也尝试了几个变体,没有要转换的变量是我们的格式,没有转换,没有成功:

CONVERT(datetime, GETDATE(), 110) AS CreatedDate, 
CONVERT(datetime, GETDATE(), 110) AS ChangedDate 

没有INSERTSELECT 语句会产生看起来非常好的值。

我在 SQL Server 2008 R2 (v10.50.2550.0) 上运行它。

在另一台服务器上该命令运行没有任何问题,为什么?

表 DDL:

CREATE TABLE [dbo].[Lookups] 
(
     [Id] [uniqueidentifier] NOT NULL,
     [Typ] [varchar](16) NOT NULL,
     [Name] [varchar](32) NOT NULL,
     [ChangedDate] [datetime] NULL,
     [ChangedName] [varchar](32) NULL,
     [CreatedDate] [datetime] NULL,
     [CreatedName] [varchar](32) NULL,

     CONSTRAINT [PK_dbo.Lookups]
         PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY];

【问题讨论】:

  • Lookups 对应的 CREATE TABLE 是什么?
  • 你能把你的表的 DDL 贴出来[DBServer].[Database].[dbo].[LkValues]吗?将GETDATE() 的值插入datetime 不会产生错误。
  • 请参阅下面 Larnu 的回答 - 如果您不指定要插入的列,则选择必须与表中列的顺序相同。在这种情况下,您试图将“A.Miller”放入更改日期。选择中的列名没有任何意义

标签: sql-server


【解决方案1】:

目前这只是一个猜测,但是,我会猜测列的顺序与SELECT 语句中的顺序不同。此外,无需将GETDATE() 的值分配给变量,您只需在SELECT 中声明即可。

假设您使用的别名是表中列的名称[DBServer].[Database].[dbo].[LkValues],那么这应该可以:

INSERT INTO Lookups (Id, [Type],[Name],CreatedName,ChangedName,CreatedDate,ChangedDate)
SELECT newid(), 
    'Type',
    [Name], 
    'A.Miller', 
    'A.Miller',
    GETDATE(),GETDATE()
FROM [DBServer].[Database].[dbo].[LkValues]
WHERE NOT [Name][] IS NULL OR [Name] = '';

编辑:我的猜测是正确的。插入表时,别名没有任何意义。这是关于您提供列的顺序,而不是它们的名称。例如:

CREATE TABLE #sample (column1 int, column2 int);

INSERT INTO #sample 
--inserts into the "wrong" columns
SELECT 2 AS column2, 1 AS column1;

SELECT *
FROM #sample;

INSERT INTO #sample (column2,
                     column1)
--Inserts into the wanted columns, as they are specified
SELECT 2, 1;

INSERT INTO #sample
--Inserts into the wanted columns, as they are in the same order as the table
SELECT 3 AS Column1, 4 AS Column2;

SELECT *
FROM #sample;

DROP TABLE #sample;

当使用INSERT 语句时,最好的做法是在INSERT 子句中指定要插入的列。这有助于其他人调试您的代码,以及您将来的代码,并轻松消除像您这样的错误。

【讨论】:

  • 是的,谢谢,对我来说也很好。较新的服务器似乎可以整理出正确的字段顺序。感谢您快速而正确的回答。
  • @Florian 似乎您的“较新”服务器的列顺序不同。无论版本如何,SQL Server 都不使用别名来确定目标列。所有当前支持的版本(2008 - 2017)都是如此。如果您的较新服务器旨在复制您当前的服务器,那么它们不是。
  • 你是对的。在另一台较新的服务器上,字段顺序就像我的第一个语句中一样,这就是它在那里工作的原因。
  • INSERT 语句中指定目标列如此重要的另一个原因@Florian。如果你的环境有不同的列顺序,那么你必须声明它们,否则你会得到不同的行为。
  • 对我的问题投赞成票会很好,谢谢。
猜你喜欢
  • 2012-04-17
  • 2017-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多