SQL Server:无法在时间戳列中插入显式值

jue*_*n d 47 sql timestamp insert sql-server-2008

使用此声明时

create table demo (
    ts timestamp
)

insert into demo select current_timestamp
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

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

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

And*_*mar 50

根据MSDN,timestamp

是一种在数据库中公开自动生成的唯一二进制数的数据类型.timestamp通常用作对表行进行版本标记的机制.存储大小为8个字节.时间戳数据类型只是一个递增的数字,不保留日期或时间.要记录日期或时间,请使用日期时间数据类型.

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


CIN*_*PPS 23

如果您需要复制完全相同的时间戳数据,请将目标表中的数据类型从timestamp更改为binary(8) - 我使用varbinary(8)并且它工作正常.

这显然打破了目标表中的任何时间戳功能,因此请确保您首先使用该功能.

  • 谢谢!在创建存档数据库以在一定时间后移动内容时,这尤其有用.在存储过程中,由于该错误,我必须将每列放在列表中,但现在我可以用*替换它,所以每次我将列添加到两个数据库中的匹配表时,我都不需要修改我的proc. (2认同)
  • 这是一个非常好的答案。我在存储过程中有一个表变量,必须在返回之前将选择查询的结果插入到该表中,将表变量中的列类型更改为 [varbinary](8) 为我解决了这个问题。 (2认同)

Vin*_*lla 13

您无法显式地将值插入timestamp列.它是自动生成的.不要在insert语句中使用此列.有关更多详细信息,请参阅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
Run Code Online (Sandbox Code Playgroud)

返回:

2014-04-04 09:20:01.153
Run Code Online (Sandbox Code Playgroud)


Eri*_*ski 8

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

答:你不能,这就是原因.

在较新版本的SQL Server中,timestamp重命名为RowVersion.这是正确的,因为时间戳非常误导.

SQL Server时间戳不是由用户设置的,并不代表日期或时间.timestamp只是一个连续数字的二进制表示,它只对确保一行在读取后没有改变是有好处的.

如果你想存储日期或时间,不使用时间戳,则必须使用其他数据类型之一,例如像datetime,smalldatetime,date,time或者DATETIME2

例如:

create table wtf (
    id INT,
    leet timestamp
)

insert into wtf (id) values (15)

select * from wtf

15    0x00000000000007D3 
Run Code Online (Sandbox Code Playgroud)

所以时间戳是某种二进制数.如果我们尝试将其投射到日期时间怎么办?

select CAST(leet AS datetime) from wtf

1900-01-01 00:00:06.677
Run Code Online (Sandbox Code Playgroud)

对我而言,今年不是1900年.所以我不确定SQL Server在想什么.


Ken*_*gel 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, '')
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

如果要将数据从一个数据库 (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
Run Code Online (Sandbox Code Playgroud)


小智 5

假设表 1 和表 2 具有三列 A、B 和时间戳。我想从 Table1 插入到 Table2。

这失败并出现时间戳错误:

Insert Into Table2
Select Table1.A, Table1.B, Table1.TimeStamp From Table1
Run Code Online (Sandbox Code Playgroud)

这有效:

Insert Into Table2
Select Table1.A, Table1.B, null From Table1
Run Code Online (Sandbox Code Playgroud)