SQL Server 2008 R2のデータベーステーブルに2つの列を追加する必要があります。
いくつかの質問を聞きたいんです:
createTS
は、行の挿入時に一度だけ設定する必要があります。この列にdatetime
タイプを試して、getdate()
のDefault ValueまたはBindingを追加したとき、列値が適切に設定されました。これがこのコラムの目的を達成する最良の方法ですか? timestamp
データ型 を考慮しましたが、それは、私の意見では、ほぼ間違った名前です!updateTS
は、行が更新される瞬間の日付と時刻に設定する必要があります。 SQL ServerにはON UPDATE CURRENT_TIMESTAMP(MySQLのように)がないため、トリガーを使用する必要があるようです。これは正しいですか、それをどうやってやるのですか?したがって、この質問に答えたい人には出発点があります。これがテーブル作成スクリプトです。
CREATE TABLE [dbo].[names]
(
[name] [nvarchar](64) NOT NULL,
[createTS] [datetime] NOT NULL CONSTRAINT [DF_names_createTS] DEFAULT (getdate()),
[updateTS] [datetime] NOT NULL,
CONSTRAINT [PK_names] PRIMARY KEY CLUSTERED
(
[name] ASC
)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
試してみる
CREATE TABLE [dbo].[Names]
(
[Name] [nvarchar](64) NOT NULL,
[CreateTS] [smalldatetime] NOT NULL CONSTRAINT CreateTS_DF DEFAULT CURRENT_TIMESTAMP,
[UpdateTS] [smalldatetime] NOT NULL
)
PS smalldatetimeで十分だと思います。異なる決定をする場合があります。
「インパクトの瞬間」にこれを行うことはできませんか?
SQL Serverでは、これは一般的です:
Update dbo.MyTable
Set
ColA = @SomeValue ,
UpdateDS = CURRENT_TIMESTAMP
Where...........
SQL Serverには「タイムスタンプ」データ型があります。
しかし、それはあなたが考えるものではないかもしれません。
参照は次のとおりです。
http://msdn.Microsoft.com/en-us/library/ms182776(v = sql.90).aspx
ここに少しあります RowVersion ( タイムスタンプの同義語 )例:
CREATE TABLE [dbo].[Names]
(
[Name] [nvarchar](64) NOT NULL,
RowVers rowversion ,
[CreateTS] [datetime] NOT NULL CONSTRAINT CreateTS_DF DEFAULT CURRENT_TIMESTAMP,
[UpdateTS] [datetime] NOT NULL
)
INSERT INTO dbo.Names (Name,UpdateTS)
select 'John' , CURRENT_TIMESTAMP
UNION ALL select 'Mary' , CURRENT_TIMESTAMP
UNION ALL select 'Paul' , CURRENT_TIMESTAMP
select * , ConvertedRowVers = CONVERT(bigint,RowVers) from [dbo].[Names]
Update dbo.Names Set Name = Name
select * , ConvertedRowVers = CONVERT(bigint,RowVers) from [dbo].[Names]
たぶん完全な実用例:
DROP TABLE [dbo].[Names]
GO
CREATE TABLE [dbo].[Names]
(
[Name] [nvarchar](64) NOT NULL,
RowVers rowversion ,
[CreateTS] [datetime] NOT NULL CONSTRAINT CreateTS_DF DEFAULT CURRENT_TIMESTAMP,
[UpdateTS] [datetime] NOT NULL
)
GO
CREATE TRIGGER dbo.trgKeepUpdateDateInSync_ByeByeBye ON dbo.Names
AFTER INSERT, UPDATE
AS
BEGIN
Update dbo.Names Set UpdateTS = CURRENT_TIMESTAMP from dbo.Names myAlias , inserted triggerInsertedTable where
triggerInsertedTable.Name = myAlias.Name
END
GO
INSERT INTO dbo.Names (Name,UpdateTS)
select 'John' , CURRENT_TIMESTAMP
UNION ALL select 'Mary' , CURRENT_TIMESTAMP
UNION ALL select 'Paul' , CURRENT_TIMESTAMP
select * , ConvertedRowVers = CONVERT(bigint,RowVers) from [dbo].[Names]
Update dbo.Names Set Name = Name , UpdateTS = '03/03/2003' /* notice that even though I set it to 2003, the trigger takes over */
select * , ConvertedRowVers = CONVERT(bigint,RowVers) from [dbo].[Names]
「名前」の値の一致はおそらく賢明ではありません。
この主流の例をSurrogateKeyで試してください
DROP TABLE [dbo].[Names]
GO
CREATE TABLE [dbo].[Names]
(
SurrogateKey int not null Primary Key Identity (1001,1),
[Name] [nvarchar](64) NOT NULL,
RowVers rowversion ,
[CreateTS] [datetime] NOT NULL CONSTRAINT CreateTS_DF DEFAULT CURRENT_TIMESTAMP,
[UpdateTS] [datetime] NOT NULL
)
GO
CREATE TRIGGER dbo.trgKeepUpdateDateInSync_ByeByeBye ON dbo.Names
AFTER UPDATE
AS
BEGIN
UPDATE dbo.Names
SET UpdateTS = CURRENT_TIMESTAMP
From dbo.Names myAlias
WHERE exists ( select null from inserted triggerInsertedTable where myAlias.SurrogateKey = triggerInsertedTable.SurrogateKey)
END
GO
INSERT INTO dbo.Names (Name,UpdateTS)
select 'John' , CURRENT_TIMESTAMP
UNION ALL select 'Mary' , CURRENT_TIMESTAMP
UNION ALL select 'Paul' , CURRENT_TIMESTAMP
select * , ConvertedRowVers = CONVERT(bigint,RowVers) from [dbo].[Names]
Update dbo.Names Set Name = Name , UpdateTS = '03/03/2003' /* notice that even though I set it to 2003, the trigger takes over */
select * , ConvertedRowVers = CONVERT(bigint,RowVers) from [dbo].[Names]
トリガーを使用する代わりに、ほとんどの列を引数として取り、データベースへの最後のINSERT
に含まれるCURRENT_TIMESTAMP
を取得するINSERT
sを処理するストアドプロシージャを作成することを検討できます。 CREATE
についても同じことができます。また、ユーザーがストアドプロシージャ以外を使用してINSERT
およびCREATE
ステートメントを実行できないように設定することもできます。
私は実際に自分でこれを行っていないことを認めなければならないので、詳細はまったくわかりません。