How do you change an autoincremented columns starting value through liquibase? - mysql

I am using MySql for my database. I have found how to set a column's starting autoincrement value when creating a table, but I need to know how to set a new starting value for an existing column. What does the liquibase script look like to do that?

The MySQL syntax is pretty straightforward:
ALTER TABLE mytable AUTO_INCREMENT = val ;
(Note that this is really a table attribute, not a column attribute. There can be only one column in a table declared to be AUTO_INCREMENT.)
This syntax isn't supported in SQL Server or Oracle; Oracle doesn't even have a concept of an "auto_increment" column, apart from a SEQUENCE object and a TRIGGER. SQL Server calls it an IDENTITY property. So I don't know how this statement would be represented in "liquibase" syntax, other than specifying that this statement is native MySQL syntax.

You can use addAutoIncrement (http://www.liquibase.org/documentation/changes/add_auto_increment.html) to change your existing AUTO_INCREMENT column.
Don't forget to specify columnDataType in the addAutoIncrement.
I used this yesterday for our project and it worked (for MySQL).

Related

Error when adding column with numeric name

I currently have a MariaDB database with columns named after dates : 20200105, 20200914 etc.
If I try to add a column using ALTER TABLE dates ADD COLUMN IF NOT EXISTS (test VARCHAR(255));, it works and the test column is created.
If I type ALTER TABLE dates ADD COLUMN IF NOT EXISTS (20201205 VARCHAR(255));, though (so, with a number replacing "test"), the creation does not work anymore and MariaDB tells me that there is an error with my SQL syntax.
I have tried to put quotes around the column name, but that does not work (not even with "test").
Is there something obvious I am missing ?
Use backticks to escape the column name:
ALTER TABLE dates ADD COLUMN IF NOT EXISTS (`20201205` VARCHAR(255));
But really best practice frowns upon the use of naming your database objects with mandatory backticks. The reason for using a name like 20201205 as a column name is that you will forever be needing to escape it using backticks. Also, from a data design point of view, your data should grow with new dates in terms of increasing the number of records, not columns.

Maria DB : Alter a field to a PERSISTENT Calculated

I have created a table and I wish to make a Computed Column from the concatenated values of three other fields in the table.
I want this Computed Field to take place at INSERT or UPDATE, so I am specifying PERSISTENT
I have tried the following code (in various ways) in phpMyAdmin but always get errors, which seem to be referencing immediately after ALTER table
I did not see a way of doing this when adding the field in phpMyAdmin, so I hoped I could ALTER it.
Alter TABLE 'tlImages'
CHANGE COLUMN tlImageQuery
AS CONCAT(tlImgTitle,"~",tlImgDescrip,"~",tlImgWhereWhen) PERSISTENT;
MariaDB version 10.0.29-MariaDB-cll-lve - MariaDB Server
phpMyAdmin . Version information: 4.0.10.18
First, lose single quotes around the table name, they are not suitable for this purpose. Use backticks or nothing.
You will still get a syntax error further in the statement, because AS clause should be in brackets. Add them.
You will still get a syntax error because you are missing column type before the AS (...) clause, add it.
You will still get a syntax error because CHANGE COLUMN needs two column names, old and new, use MODIFY instead.
Alter TABLE `tlImages`
MODIFY COLUMN tlImageQuery VARCHAR(128)
AS (CONCAT(tlImgTitle,"~",tlImgDescrip,"~",tlImgWhereWhen)) PERSISTENT
;
(Type VARCHAR(128) is given just as an example).

Change MySQL numerical field to char using a function

I have a table in MySQL DB with a field for storing IP address. It stores it as a number (int). I'd like to change the structure to use string (char) instead.
Is it possible with single ALTER TABLE statement? As far as I can see in Postgres it is possible to specify a conversion function to ALTER TABLE, but I don't see an equivalent for MySQL.
A workaround is of course to:
alter table by adding a new char() field
update that new field from the old one using inet_ntoa
alter table by removing old field
and finally renaming new field to the same name as the old one had
But maybe there is a simpler solution?
You can simply alter the column to varchar. mysql will automatically convert the values. I can confirm this with mysql 5.6.
but before you do this, you should definetely create a backup and maybe try this with a small test table.

Insert into table with auto-increment field

I have two tables called HRData and HRDataHistory. HRDataHistory has the same structure as HRData except the first column is an autoincrement field and the last column is a DateTime field.
HRData has a trigger:
CREATE TRIGGER [HR].[HRData_History]
ON [HR].[HRData]
AFTER INSERT, UPDATE
AS
INSERT INTO HR.HRDataHistory
SELECT *, GETDATE()
FROM inserted
;
GO
This is working on an existing development machine. I am trying to mirror this relationship on my local sql server instance so that I can test some changes. Using SSMS I used 'Script Table as Create To...' and created the structure of each table and index on my local sql server instance. However when I do this for the trigger I get the following error:
An explicit value for the identity column in table 'HR.HRDataHistory' can only be specified when a column list is used and IDENTITY_INSERT is ON.
I know the preferred method would be to specify the columns, but I want to mirror production which does not currently do that and further I want to understand why it is working in production but not on my test database.
You're getting this error because you're trying to insert data into an IDENTITY column, which auto-populates itself whenever you insert another row in that table.
Off the top of my head, you can do something like below (although I believe there are more elegant solutions and I do not guarantee that this is a safe solution, nor have I tried something like this and I recommend testing on a TEST database before trying in production/LIVE):
add another column to HRDataHistory table which does not have identity set on it (because you cannot remove identity form a colum once set), but must have the same datatype as the current ID (IDENTITY) column
use a UPDATE query to move all of your ID's from your IDENTITY column to your new column:
UPDATE HRDataHistory
SET new_column = ID
Drop the IDENTITY column (but this might have grave implications if you have any FK set on it and possibly other objects that use it):
ALTER TABLE HRDataHistory
DROP COLUMN ID
Rename the "new_column" to the name of your previous IDENTITY column:
EXEC sp_RENAME 'HRDataHistory.new_column' , 'ID', 'COLUMN'
At this point I believe you can use your trigger to "copy" the newly inserted data from the HRData table into the HRDataHistory, since the column names should match and there is no more conflict due to IDENTITY.
Again, this might (not guaranteed) work so I recommend you first check on a TEST environment.

Postgresql setting next id to write to

I recently migrated a database from mysql to pgsql 9.
But now when I try to create a new object (in django admin) it tells me that the id I'm trying to use (started at one and has increased each time I tried) is already used.
I'm guessing that there is a pointer or index which needs to be set to the last used id. Am I correct?
When you define your table, the PostgreSQL equivalent to 'auto_increment' is:
CREATE TABLE foo (
id SERIAL,
...
);
If your table is already created (as I suspect it is), you can add this manually:
CREATE SEQUENCE foo_id_seq;
ALTER TABLE foo ALTER COLUMN id SET DEFAULT nextval('foo_id_seq');
Note that if you want to stick with the default name that Pg would have given you use the following format for your sequence name:
<table name>_<column name>_seq
Thus in my example, foo_id_seq.
If the table was migrated and it uses serial to replace the mysql auto increment column, your data was probably migrated without incrementing the serial sequence. Look up the postgresql setval function to set your sequence to a value above the highest existing key in your table.