【问题标题】:SQL Server: Cannot insert an explicit value into a timestamp columnSQL Server:无法将显式值插入时间戳列
【发布时间】:2012-05-02 23:53:00
【问题描述】:

使用此语句时

create table demo (
    ts timestamp
)

insert into demo select current_timestamp

我收到以下错误:

无法将显式值插入时间戳列。将 INSERT 与列列表一起使用以排除时间戳列,或将 DEFAULT 插入时间戳列

如何将当前时间插入timestamp 列?

【问题讨论】:

标签: sql sql-server-2008 insert timestamp


【解决方案1】:

According to MSDN, timestamp

是一种数据类型,它公开自动生成的唯一二进制文件 数据库中的数字。时间戳一般用作一种机制 用于版本标记表行。存储大小为 8 个字节。这 时间戳数据类型只是一个递增的数字,而不是 保留日期或时间。要记录日期或时间,请使用日期时间 数据类型。

您可能正在寻找 datetime 数据类型。

【讨论】:

    【解决方案2】:

    如果您需要复制完全相同的时间戳数据,请将目标表中的数据类型从时间戳更改为二进制(8)——我使用了 varbinary(8),它工作正常。

    这显然会破坏目标表中的任何时间戳功能,因此请先确保您没问题。

    【讨论】:

    • 谢谢!这在创建存档数据库以在一定时间后将内容移至其中时特别有用。在存储的过程中,由于该错误,我必须将每一列都放在列表中,但现在我可以用 * 替换它,所以每次我将列添加到两个数据库中的匹配表时,我都不需要修改我的过程。
    • 如果您需要为部分结果使用表变量并且希望将原始时间戳包含在最终结果中,这也很有用
    • 这是一个很好的答案。我在存储过程中有一个表变量,必须在返回之前将选择查询的结果插入到该表中,将表变量中的列类型更改为 [varbinary](8) 为我解决了这个问题。
    【解决方案3】:

    您不能将值显式插入时间戳列。它是自动生成的。不要在插入语句中使用此列。详情请参考http://msdn.microsoft.com/en-us/library/ms182776(SQL.90).aspx

    您可以像这样使用日期时间而不是时间戳:

    create table demo (
        ts datetime
    )
    
    insert into demo select current_timestamp
    
    select ts from demo
    

    返回:

    2014-04-04 09:20:01.153
    

    【讨论】:

      【解决方案4】:

      如何使用 SQL Server 将当前时间插入时间戳:

      在较新版本的 SQL Server 中,timestamp 被重命名为 RowVersion。没错,因为时间戳名称具有误导性。

      SQL Server 的timestamp 不是由用户设置的,不代表日期或时间。时间戳仅有助于确保行在被读取后没有发生变化。

      如果您想存储日期或时间,请勿使用时间戳,您必须使用其他数据类型之一,例如 datetimesmalldatetimedatetimeDATETIME2

      例如:

      create table wtf (
          id INT,
          leet timestamp
      )
      
      insert into wtf (id) values (15)
      
      select * from wtf
      
      15    0x00000000000007D3 
      
      mssql 中的

      'timestamp' 是某种内部数据类型。将该数字转换为 datetime 会产生一个无意义的数字。

      【讨论】:

        【解决方案5】:

        假设 Table1 和 Table2 有三列 A、B 和 TimeStamp。我想从 Table1 插入 Table2。

        这会因时间戳错误而失败:

        Insert Into Table2
        Select Table1.A, Table1.B, Table1.TimeStamp From Table1
        

        这行得通:

        Insert Into Table2
        Select Table1.A, Table1.B, null From Table1
        

        【讨论】:

          【解决方案6】:

          这些答案中有一些很好的信息。假设您正在处理无法更改的数据库,并且您正在将数据从一个版本的表复制到另一个版本,或者从一个数据库中的同一个表复制到另一个。还假设有很多列,并且您需要来自所有列的数据,或者您不需要的列没有默认值。您需要编写一个包含所有列名的查询。

          这是一个返回表的所有非时间戳列名称的查询,您可以将其剪切并粘贴到插入查询中。仅供参考:189 是时间戳的类型 ID。

          declare @TableName nvarchar(50) = 'Product';
          
          select stuff(
              (select 
                  ', ' + columns.name
              from 
                  (select id from sysobjects where xtype = 'U' and name = @TableName) tables
                  inner join syscolumns columns on tables.id = columns.id
              where columns.xtype <> 189
              for xml path('')), 1, 2, '')
          

          只需将顶部的表格名称从“产品”更改为您的表格名称。查询将返回列名列表:

          ProductID, Name, ProductNumber, MakeFlag, FinishedGoodsFlag, Color, SafetyStockLevel, ReorderPoint, StandardCost, ListPrice, Size, SizeUnitMeasureCode, WeightUnitMeasureCode, Weight, DaysToManufacture, ProductLine, Class, Style, ProductSubcategoryID, ProductModelID, SellStartDate, SellEndDate, DiscontinuedDate, rowguid, ModifiedDate
          

          如果您要将数据从一个数据库 (DB1) 复制到另一个数据库 (DB2),您可以使用此查询。

          insert DB2.dbo.Product (ProductID, Name, ProductNumber, MakeFlag, FinishedGoodsFlag, Color, SafetyStockLevel, ReorderPoint, StandardCost, ListPrice, Size, SizeUnitMeasureCode, WeightUnitMeasureCode, Weight, DaysToManufacture, ProductLine, Class, Style, ProductSubcategoryID, ProductModelID, SellStartDate, SellEndDate, DiscontinuedDate, rowguid, ModifiedDate)
          select ProductID, Name, ProductNumber, MakeFlag, FinishedGoodsFlag, Color, SafetyStockLevel, ReorderPoint, StandardCost, ListPrice, Size, SizeUnitMeasureCode, WeightUnitMeasureCode, Weight, DaysToManufacture, ProductLine, Class, Style, ProductSubcategoryID, ProductModelID, SellStartDate, SellEndDate, DiscontinuedDate, rowguid, ModifiedDate 
          from DB1.dbo.Product
          

          【讨论】:

          • 完美的肯特。我一直在寻找这样的东西。谢谢你:)
          【解决方案7】:

          创建表演示 ( id int, ts 时间戳 )

          插入演示(id,ts) 值(1,默认)

          【讨论】:

          • 这个答案至少承认了我觉得令人困惑的部分错误消息,尽管它并没有真正回答用户的问题(我不是拒绝回答的人)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-08-08
          • 2017-08-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-11
          相关资源
          最近更新 更多