web-dev-qa-db-ja.com

SQL Server:タイムスタンプ列に明示的な値を挿入できません

このステートメントを使用する場合

create table demo (
    ts timestamp
)

insert into demo select current_timestamp

次のエラーが表示されます。

タイムスタンプ列に明示的な値を挿入できません。列リストでINSERTを使用してタイムスタンプ列を除外するか、DEFAULTをタイムスタンプ列に挿入します

現在の時刻をtimestamp列に挿入するにはどうすればよいですか?

44
juergen d

MSDNによるとtimestamp

データベース内で自動的に生成された一意の2進数を公開するデータ型です。タイムスタンプは一般に、バージョンスタンプテーブル行のメカニズムとして使用されます。ストレージサイズは8バイトです。タイムスタンプデータ型は単なる増分値であり、日付や時刻は保持されません。日付または時刻を記録するには、日時データ型を使用します。

おそらく、代わりにdatetimeデータ型を探しているでしょう。

48
Andomar

まったく同じタイムスタンプデータをコピーする必要がある場合は、宛先テーブルのデータ型をタイムスタンプからbinary(8)に変更します-私はvarbinary(8)を使用し、正常に機能しました。

これにより、宛先テーブルのタイムスタンプ機能が明らかに破損するため、最初に問題ないことを確認してください。

21
CINCHAPPS

タイムスタンプ列に値を明示的に挿入することはできません。自動生成されます。 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

返却値:

2014-04-04 09:20:01.153
13

SQL Serverで現在の時刻をタイムスタンプに挿入する方法:

回答:できません。その理由は次のとおりです。

SQL Serverの新しいバージョンでは、timestampRowVersionに名前が変更されます。タイムスタンプは非常に誤解を招くので、そうです。

SQL ServerのタイムスタンプIS NOTはユーザーによって設定され、日付や時刻を表しません。タイムスタンプは連続した数字の単なるバイナリ表現であり、行が変更されていないことを確認する場合にのみ有効です読まれてから。

日付または時刻を保存する場合、タイムスタンプを使用しないでください。たとえば、datetimesmalldatetimedatetimeDATETIME2など、他のデータ型のいずれかを使用する必要があります。

例えば:

create table wtf (
    id INT,
    leet timestamp
)

insert into wtf (id) values (15)

select * from wtf

15    0x00000000000007D3 

したがって、タイムスタンプはある種の2進数です。 datetimeにキャストしようとするとどうなりますか?

select CAST(leet AS datetime) from wtf

1900-01-01 00:00:06.677

私の現在の年は1900年ではありません。そのため、SQL Serverが何を考えているのかわかりません。

8
Eric Leschinski

Table1とTable2には3つの列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
3

これらの回答にはいくつかの良い情報があります。変更できないデータベースを扱っており、あるバージョンのテーブルから別のバージョンに、またはあるデータベースの同じテーブルから別のバージョンにデータをコピーしているとします。また、多数の列があり、すべての列のデータが必要であるか、不要な列にデフォルト値がないと仮定します。すべての列名を使用してクエリを作成する必要があります。

以下は、テーブルのタイムスタンプ以外のすべての列名を返すクエリです。挿入クエリにカットアンドペーストできます。参考までに: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
1
Kent Weigel