web-dev-qa-db-fra.com

SQL Server: impossible d'insérer une valeur explicite dans une colonne d'horodatage

Lorsque vous utilisez cette déclaration

create table demo (
    ts timestamp
)

insert into demo select current_timestamp

Je reçois l'erreur suivante:

Impossible d'insérer une valeur explicite dans une colonne d'horodatage. Utilisez INSERT avec une liste de colonnes pour exclure la colonne timestamp ou insérez un DEFAULT dans la colonne timestamp.

Comment insérer l'heure actuelle dans une colonne timestamp?

44
juergen d

Selon MSDN , timestamp

Type de données qui expose des nombres binaires uniques générés automatiquement dans une base de données. timestamp est généralement utilisé en tant que mécanisme d’estampage de version des lignes d’un tableau. La taille de stockage est de 8 octets. Le type de données d'horodatage est juste un nombre incrémentant et ne conserve pas une date ou une heure. Pour enregistrer une date ou une heure, utilisez un type de données datetime.

Vous recherchez probablement le type de données datetime.

48
Andomar

Si vous avez besoin de copier exactement les mêmes données d’horodatage, modifiez le type de données dans la table de destination d’horodatage à binaire (8) - j’ai utilisé varbinary (8) et cela a fonctionné correctement.

Cela casse évidemment toutes les fonctionnalités d'horodatage de la table de destination, alors assurez-vous que tout va bien pour vous.

21
CINCHAPPS

Vous ne pouvez pas insérer les valeurs dans la colonne d'horodatage explicitement. Il est généré automatiquement. N'utilisez pas cette colonne dans votre instruction insert. Reportez-vous à http://msdn.Microsoft.com/en-us/library/ms182776 (SQL.90) .aspx pour plus de détails.

Vous pouvez utiliser un datetime au lieu d'un horodatage comme ceci:

create table demo (
    ts datetime
)

insert into demo select current_timestamp

select ts from demo

Résultats:

2014-04-04 09:20:01.153
13
Vinay Kumar Chella

Comment insérer l'heure actuelle dans un horodatage avec SQL Server:

Réponse: Vous ne pouvez pas et voici pourquoi.

Dans les versions plus récentes de SQL Server, timestamp est renommé en RowVersion. À juste titre, car l'horodatage est très trompeur.

Horodatage SQL Server IS NON défini par l'utilisateur et ne représente pas une date ou une heure. Timestamp est simplement une représentation binaire d'un nombre consécutif, il ne sert qu'à s'assurer qu'une ligne n'a pas changé. depuis qu'il a été lu.

Si vous souhaitez stocker une date ou une heure, n'utilisez pas d'horodatage, vous devez utiliser l'un des autres types de données, comme par exemple datetime, smalldatetime, date, time ou DATETIME2

Par exemple:

create table wtf (
    id INT,
    leet timestamp
)

insert into wtf (id) values (15)

select * from wtf

15    0x00000000000007D3 

Donc, l'horodatage est une sorte de nombre binaire. Et si nous essayons de le diffuser à datetime?

select CAST(leet AS datetime) from wtf

1900-01-01 00:00:06.677

L'année en cours pour moi n'est pas 1900. Je ne suis donc pas sûr de ce que pense SQL Server.

8
Eric Leschinski

Supposons que Table1 et Table2 ont trois colonnes A, B et TimeStamp. Je veux insérer de Table1 dans Table2.

Cela échoue avec l'erreur d'horodatage:

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

Cela marche:

Insert Into Table2
Select Table1.A, Table1.B, null From Table1
3
Keith Liebenberg

Il y a quelques bonnes informations dans ces réponses. Supposons que vous traitez avec des bases de données que vous ne pouvez pas modifier et que vous copiez des données d'une version de la table à une autre, ou de la même table d'une base de données à une autre. Supposons également qu'il y a beaucoup de colonnes et que vous avez besoin de données de toutes les colonnes ou les colonnes dont vous n'avez pas besoin n'ont pas de valeurs par défaut. Vous devez écrire une requête avec tous les noms de colonnes.

Voici une requête qui renvoie tous les noms de colonne non horodatés d'une table, que vous pouvez couper et coller dans votre requête d'insertion. FYI: 189 est l'ID de type pour l'horodatage.

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, '')

Il suffit de changer le nom de la table en haut de "Produit" pour le nom de votre table. La requête retournera une liste de noms de colonnes:

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

Si vous copiez des données d'une base de données (DB1) vers une autre base de données (DB2), vous pouvez utiliser cette requête.

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
1
Kent Weigel