Multiple timestamp columns in SQL Server 2000 - sql-server

I need to create a table in SQL Server 2000.
create table TABLE (
DBID_ bigint not null,
CLASS_ varchar(255) not null,
DBVERSION_ integer not null,
HPROCI_ bigint,
TYPE_ varchar(255),
EXECUTION_ varchar(255),
ACTIVITY_NAME_ varchar(255),
START_ timestamp,
END_ timestamp,
DURATION_ bigint,
TRANSITION_ varchar(255),
NEXTIDX_ integer,
HTASK_ bigint,
primary key (DBID_)
);
An error occurs when I run it.
A table can only have one timestamp column. Because table TABLE
already has one, the column END_ cannot be added.
What is the best alternative for timestamp for SQL Server? How to fix this issue?

A timestamp is not a datetime datatype as the name suggests. It is an internal value that is relative to the server's clock, but an actual time cannot be derived from it's value. It is simply used to evaluate whether a row has been updated, and thus a table can only have one column of this type. The timestamp syntax is actually deprecated and is now named rowversion which makes a lot more sense.
Given your column names (Start, End) I assume you are trying to store actual timestamps, and should instead be using datetime as your datatype.

In Sql Server timestamp is a data type and it's not a time.
It's basically a way of versioning a record and it's used for optimistic locking in a disconnected database model
When you load up the record, you pick up the timestamp column. You only write it back if the value in the timestamp column is the same, as that means no one else has changed it since you got it.
If you want a real datetime value, add a datetime either not null, or with a default of GetDate() and remember to update every update.

Related

Adding table records with type Date manually

I'm using Visual Studio connected to my SQL Server to create a new database and populate a table with some mock data for application development testing. I created a table with 5 fields, an auto-increment PK, three nvarchar(50) fields and a date. When I view the table data and attempt to add a row, it doesn't allow me to type into the Date field nor give me any way to insert a date into the field. How can I accomplish this?
I was not descriptive enough and it turns out it was a confusion between a timestamp and a datetime datatype. I was trying to use timestamp thinking when I did an insert it would give the CURRENT_TIMESTAMP. As it turns out the timestamp is really rowversion and has nothing to do with an actual datetime. I have since changed the datatype to datetime and have had no problems.

How do I preserve timestamp values when altering a table in SQL Server (T-SQL)?

Or: how to copy timestamp data from one table to another?
Using SQL Server 2008 and having old design documents which requires a table to has the columns ordered in a certain way (with timestamp column last, something I guess comes from the time when Excel was used instead of an SQL database) I need to add a column in the middle of a table, keeping the timestamp data intact...
Do you know how to instruct SQL Server to do this?
Example T-SQL code:
-- In the beginning...
CREATE TABLE TestTableA
(
[TestTableAId] [int] IDENTITY(1,1) NOT NULL,
[TestTableAText] varchar(max) NOT NULL,
[TestTableATimeStamp] [timestamp] NOT NULL
)
INSERT INTO TestTableA (TestTableAText) VALUES ('TEST')
-- Many years pass...
-- Now we need to add a column to this table, but preserve all data, including timestamp data.
-- Additional requirement: We want SQL Server to keep the TimeStamp last of the column.
CREATE TABLE TestTableB
(
[TestTableBId] [int] IDENTITY(1,1) NOT NULL,
[TestTableBText] varchar(max) NOT NULL,
[TestTableBInt] [int] NULL,
[TestTableBTimeStamp] [timestamp] NOT NULL
)
-- How do we copy the timestamp data from TestTableATimestamp to `TestTableBTimestamp`?
SET IDENTITY_INSERT [TestTableB] ON
-- Next line will produce errormessage:
-- Cannot insert an explicit value into a timestamp column. Use INSERT with a column list to exclude the timestamp column, or insert a DEFAULT into the timestamp column.
INSERT INTO [TestTableB] (TestTableBId, TestTableBText, TestTableBTimeStamp)
SELECT TestTableAId, TestTableAText, TestTableATimestamp
FROM TestTableA
SET IDENTITY_INSERT [TestTableB] OFF
GO
Suggestions?
Drop table TestTableB first and then run a query:
SELECT
TestTableAId AS TestTableBId,
TestTableAText AS TestTableBText,
cast(null as int) as TestTableBInt,
TestTableATimestamp AS TestTableBTimeStamp
INTO TestTableB
FROM TestTableA
First check requirements: It depends if you need to preserve the timestamps. You actually may not, since they are just ROWVERSION values and don't actually encode the time in any way. So check that.
Why you might not want to preserve them: The only purpose of TIMESTAMP or ROWVERSION is to determine if the row has changed since last being read. If you are adding a column, you may want this to be seen as a change, particularly if the default is non-null.
If you DO need to preserve the timestamps see Dmitry's answer.

Correct SQL to convert mySQL tables to SQL Server tables

I have a number of tables I need to convert from mySQL to SQL Server.
An Example of a mySQL Table is
CREATE TABLE `required_items` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'Unique Barcode ID',
`fk_load_id` INT( 11 ) NOT NULL COMMENT 'Load ID',
`barcode` VARCHAR( 255 ) NOT NULL COMMENT 'Barcode Value',
`description` VARCHAR( 255 ) NULL DEFAULT NULL COMMENT 'Barcode Description',
`created` TIMESTAMP NULL DEFAULT NULL COMMENT 'Creation Timestamp',
`modified` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Modified Timestamp',
FOREIGN KEY (`fk_load_id`) REFERENCES `loads`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB CHARACTER SET ascii COLLATE ascii_general_ci COMMENT = 'Contains Required Items for the Load';
And a trigger to update the created date
CREATE TRIGGER required_items_before_insert_created_date BEFORE INSERT ON `required_items`
FOR EACH ROW
BEGIN
SET NEW.created = CURRENT_TIMESTAMP;
END
Now I need to create tables similar to this in SQL Server. There seems to be a lot of different data types available so I am unsure which to use.
What data type should I use to the primary key column
(uniqueidentifier, bigint, int)?
What should I use for the timestamps
(timestamp, datatime, datetime2(7))?
How should I enforce the created
and modified timestamps (currently I am using triggers)?
How can I enforce foreign key constraints.
Should I be using Varchar(255) in SQL Server? (Maybe Text, Varchar(MAX) is better)
I am using Visual Studio 2010 to create the tables.
First of all, you can probably use PHPMyAdmin (or something similar) to script out the table creation process to SQL Server. You can take a look at what is automatically created for you to get an idea of what you should be using. After that, you should take a look at SSMS (SQL Server Management Studio) over Visual Studio 2010. Tweaking the tables that your script will create will be easier in SSMS - in fact, most database development tasks will be easier in SSMS.
What data type should I use to the primary key column (uniqueidentifier, bigint, int)?
Depending on how many records you plan to have in your table, use int, or bigint. There are problems with uniqueidentfiers that you will probably want to avoid. INT vs Unique-Identifier for ID field in database
What should I use for the timestamps (timestamp, datatime, datetime2(7))?
timestamps are different in SQL Server than in MySQL. Despite the name, a timestamp is an incrementing number that is used as a mechanism to version rows. http://msdn.microsoft.com/en-us/library/ms182776%28v=sql.90%29.aspx . In short though, datetime is probably your best bet for compatibility purposes.
How should I enforce the created and modified timestamps (currently I am using triggers)?
See above. Also, the SQL Server version of a "Timestamp" is automatically updated by the DBMS. If you need a timestamp similar to your MySQL version, you can use a trigger to do that (but that is generally frowned upon...kind of dogmatic really).
How can I enforce foreign key constraints.
You should treat them as you would using innoDB. See this article for examples of creating foreign key constraints http://blog.sqlauthority.com/2008/09/08/sql-server-%E2%80%93-2008-creating-primary-key-foreign-key-and-default-constraint/
Should I be using Varchar(255) in SQL Server? (Maybe Text, Varchar(MAX) is better)
That depends on the data you plan to store in the field. Varchar max is equivalent to varchar(8000) and if you don't need varchar(255), you can always set it to a lower value like varchar(50). Using a field size that is too large has performance implications. One thing to note is that if you plan to support unicode (multilingual) data in your field, use nvarchar or nchar.

SQLserver Timestamp trying to set a default getting unreadable result

I have a time stamp field in a table and I've unticked the box in designer for allowing Nulls
I'm unable to enter anything in default value and binding field ( this is greyed out and doesn't allow you type anything )
I'm trying all my sql experiments out in the query designer of sql server express 2008
If I Insert a new record into the table the timestamp field gives a value that looks like:
0x00000000000007D7
As you can see this is totally unreadable:
How can I get round this/ get a readable time stamp in there?
Use DATETIME with a default constraint of GETDATE
You can do that like this:
CREATE TABLE myTable
(
ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
myTimeStamp datetime NOT NULL DEFAULT GETDATE()
)
TIMESTAMP is a binary field used for row versioning and cannot be edited.
From BOL:
timestamp is a data type that exposes automatically generated binary numbers, which are guaranteed to be unique within a database.
timestamp is used typically as a mechanism for version-stamping table
rows. The storage size is 8 bytes.

Is it possible to alter a SQL Server table column datatype from bigint to varchar after it has been populated?

I have a SQL Server 2008 table which contains an external user reference currently stored as a bigint - the userid from the external table. I want to extend this to allow email address, open ID etc to be used as the external identifier. Is it possible to alter the column datatype from bigint to varchar without affecting any of the existing data?
Yes, that should be possible, no problem - as long as you make your VARCHAR field big enough to hold you BIGINT values :-)
You'd have to use something like this T-SQL:
ALTER TABLE dbo.YourTable
ALTER COLUMN YourColumnName VARCHAR(50) -- or whatever you want
and that should be it! Since all BIGINT values can be converted into a string, that command should work just fine and without any danger of losing data.

Resources