SQL simplist way to update an INT identity column - sql

I have a column called fixedID, and it's current Value = 2, I want to update this value to be 42. What is the best way to do this. I would like to do this modification as simply as possible. However, if I could do this while doing an select insert that would be fantastic also.
update tblFixedId
set FixedId = (FixedId + 400)
possible to change the value here?
Select * INTO mynewTable from myOldertable

Identity columns are not updatable in SQL Server.
The only way of doing this as an actual UPDATE rather than a DELETE ... INSERT would be to use ALTER TABLE ... SWITCH to mark the column as no longer an IDENTITY column, do the UPDATE then ALTER TABLE ... SWITCH again to re-mark the column as IDENTITY (For example code the first way round see the workarounds on this Connect Item and for the second way here).
Note that in the common scenario that the identity column is the clustered index key the Update will likely be implemented as an INSERT ... DELETE anyway.

Related

Inserting new rows and generate a new id based on the current last row

The primary key of my table is an Identity column of an ID. I want to be able to insert a new row and have it know what the last ID in the table currently is and add one to it. I know I can use Scope Identity to get the last inserted column from my code, but I am worried about people manually adding entries in the database, because they do this quite often. Is there a way I can look at the last ID in the table and not just the last ID my code inserted?
With a SQL Identity column, you don't need to do anything special. This is the default behavior. SQL Server will handle making sure you don't have collisions regardless of where the inserts come from.
The ##Identity will pull the latest identity, and scope_identity will grab the identity from the current scope.
A scope is a module: a stored procedure, trigger, function, or batch. Therefore, if two statements are in the same stored procedure, function, or batch, they are in the same scope.
If you don't want to allow manual entries to the primary column, then you can add Identity constraint to it along with primary key constraint.
Example, while creating a table,
CREATE Table t_Temp(RowID Int Primary Key Identity(1,1), Name Varchar(50))
INSERT Into t_Temp values ('UserName')
INSERT Into t_Temp values ('UserName1')
SELECT * from t_Temp
You can query the table and get the next available code in one SQL query:
SELECT COALESCE(MAX(CAST("RowID" AS INT)),0) +1 as 'NextRowID' from <tableName>
The "0" here is a default, meaning if there are no rows found, the first code returned would be (0+1) =1
Generally I have 999 instead of the 0 as I like my RowID/primary key etc. to start at 1000.

Can Identity Column help perform update statement

I need to do updates over a table that contains over 600M lines on sql server, and this table does not contain the identity column, this is how it works by far :
UPDATE myTable set myBitColmun=1 where key='specifickey'
This kind of query takes over 1minute to update this specific line. And imagine the time needed to do updates on the whole table. And I need to do this kind of updates on my table everytime possible.
My question is : can identity column help perform update statement ?
alter table myTable
add id int identity(1,1)
and change my previous query:
UPDATE myTable set myBitColmun=1 where id=specificId

Calculate non-standard auto-increment automatically

The table I am working with does not have a standard auto-increment field to use as a primary key, so I need to come up with a way to automatically calculate the value that should be used in the field.
My first thought was to create a trigger to happen AFTER INSERT, however, as far as I can tell, there's no easy way to reference the row that was just inserted. I could do something like
UPDATE `table` SET `reference_number` = (SELECT ....) WHERE `reference_number` IS NULL
but because reference_number is a PRIMARY KEY, it cannot be null. (Does that mean it would be an empty string ''?)
Is there a better way to do this?
CREATE TRIGGER mkuuid BEFORE INSERT ON SomeTable
FOR EACH ROW BEGIN
SET NEW.primary_key = UUID_SHORT();
END

Is there an easy way to add a custom migration script to SQL Compare scripts?

At my work we are currently having some serious pains pushing our database changes across environments. The issue starts to show up when we create a new non-nullable column on an existing table. The script that SQL Compare generates creates the column as non-nullable, so it will always fail. I was hoping that there was some alternative to having to manually edit the script. Is there any way to get around this? If not, how do you guys handle it?
Create a table:
create table #bingo ( id int )
Add a value:
insert into #bingo values (1)
Add a new column:
alter table #bingo add userid int
Populate the new column:
update #bingo set userid = 1 where id = 1
Change the new column to not nullable:
alter table #bingo alter column userid int not null
You would have to manually edit the RedGate Sql Compare to make it work like this.
How do you plan on filling the NOT NULL column? I don't see how SQL Compare could really come up with a solution since it has no way of knowing how you would fill it.
You could create the column with a DEFAULT, then simply add an update statement at the end of the generated scripts to properly update the column if you have some source for the values.
add a default onto the new not null column
when creating a new not null column, what value do all the existing rows get? If you don't know, make the column nullable.

Change each record in a table with no primary key?

I have a table in a database that represents dates textually (i.e. "2008-11-09") and I would like to replace them with the UNIX timestamp. However, I don't think that MySQL is capable of doing the conversion on its own, so I'd like to write a little script to do the conversion. The way I can think to do it involves getting all the records in the table, iterating through them, and updating the database records. However, with no primary key, I can't easily get the exact record I need to update.
Is there a way to get MySQL to assign temporary IDs to records during a SELECT so that I refer back to them when doing UPDATEs?
Does this not do it?
UPDATE
MyTable
SET
MyTimeStamp = UNIX_TIMESTAMP(MyDateTime);
If for some reason you do have to iterate (the other answers cover the situation where you don't), I can think of two ways to do it (these aren't MySQL-specific):
Add a column to the table that's an auto-assigned number. Use that as the PK for your updates, then drop the column afterwards (or just keep it around for future use).
In a table with no defined PK, as long as there are no exact duplicate rows, you can use the entire row as a composite PK; just use every column in the row as your distinguishing characteristic. i.e., if the table has 3 columns, "name", "address", and "updated", do the following:
UPDATE mytable SET updated = [timestamp value] WHERE name = [name] AND address = [address] AND timestamp = [old timestamp]
Many data access frameworks use this exact strategy to implement optimistic concurrency.
No, you should be able to do this with a single update statement. If all of the dates are yyyy-mm-dd and they are just stored in some sort of text column instead of DATETIME, you can just move the data over. SQL would be like:
ALTER TABLE t ADD COLUMN dates DATETIME;
UPDATE t set t.dates=t.olddate;
This shouldn't be dependent on a PK because MySQL can scan through each row in the table. The only time PK's become an issue is if you need to update a single row, but the row may not be unique.
You can generate values during a SELECT using the MySQL user variables feature, but these values do not refer to the row; they're temporary parts of the result set only. You can't use them in UPDATE statements.
SET #v := 0;
SELECT #v:=#v+1, * FROM mytable;
Here's how I'd solve the problem. You're going to have to create another column for your UNIX timestamps anyway, so you can add it first. Then convert the values in the old datetime column to the UNIX timestamp and place it in the new column. Then drop the old textual datetime column.
ALTER TABLE mytable ADD COLUMN unix_timestamp INT UNSIGNED NOT NULL DEFAULT 0;
UPDATE mytable
SET unix_timestamp = UNIX_TIMESTAMP( STR_TO_DATE( text_timestamp, '%Y-%m-%d' ) );
ALTER TABLE mytable DROP COLUMN text_timestamp;
Of course you should confirm that the conversion has been done correctly before you drop the old column!
See UNIX_TIMESTAMP() and STR_TO_DATE()