Liquibase Update Command doesn't drop elements (tables, functions, procedure...) from my database despite SQL script absent from my solution - liquibase

I use liquibase tool to manage a postgres database. I work as the following :
I have a solution composed of different folders containing SQL scripts responsible for schema creation, tables creations, types creation, procedures creation, etc... Then, I have a ChangeLog file in xml format, containing the following informations :
includeAll path="#{Server.WorkingDirectory}#/02 - Schema" relativeToChangelogFile="false"
includeAll path="#{Server.WorkingDirectory}#/03 - Types" relativeToChangelogFile="false
includeAll path="#{Server.WorkingDirectory}#/04 - Tables" relativeToChangelogFile="false"
includeAll path="#{Server.WorkingDirectory}#/05 - Fonctions" relativeToChangelogFile="false"
includeAll path="#{Server.WorkingDirectory}#/06 - Stored Procedures" relativeToChangelogFile="false"
I run liquibase via command line :
liquibase --changeLogFile=$(Changelog.File.Name) --driver=$(Driver.Name) --classpath=$(Driver.Classpath) --url=$(BDD.URL) --username=$(BDD.Login) --password=$(BDD.Password) update
This enable Liquibase to take all the SQL scripts in the different folders listed in the changelogFile, compare it with the current database at url $(BDD.URL), and generate a delta script containing all the SQL queries to be executed to have a database corresponding to my solution.
This works well when I add new scripts (new tables or procedures) or modify existing scripts, my database is correctly updated by the command line, as expected. BUT it does not do anything when I delete a script from my solution.
To be more factual, here is what I want :
I have a SQL file containing the query "CREATE TABLE my_table" located in the folder "04 - Tables".
I execute the update command above, and it creates the table "my_table" in my database.
I finally do not want this table in my database any more. Thus I would like to simply remove the corresponding SQL script from my solution, and then run again the "update" command to simply remove my table in my database, generating automatically a "DROP TABLE my_table" by the liquibase "update" command. But this is not working as Liquibase doesn't record any change when I remove a sql file (whereas it does when I add or modify a file).
Does anyone know a solution to this ? Is there a specific command to drop an element when there is no "CREATE" query for this element, in a SQL solution ?
Many thanks in advance for you help :)

You will need to explicitly write a script to drop the table.
Other option is to rollback the change IF YOU HAVE Specified the Rollback SQL as part of your original SQL script.
There is a Pro Version option to rollback a single update , with free / community version, you can rollback last few changes in sequence
ex; I did "liquibase rollbackCount 5" will rollback the last 5 changes that were applied ONLY IF I HAD Coded the rollback sql needed as part of my script.
My Sql script sample that included the code to rollback is
--rollback drop TABLE test.user1 ; drop table test.cd_activity;
CREATE TABLE test.user1 (
user_type_id int NOT NULL
);
CREATE TABLE test.cd_activity (
activity_id Integer NOT NULL
userid int);

Related

Getting error when trying to Rename multiple tables in SPROC in DB2

I've created a DB2 sql script that populates a static table and then does a rename to swap out the live table with the newly updated one. Its a fairly large SQL script so I'm only including the areas that Im having a an error on.
I'm getting the error: "[IBM][CLI Driver][DB2/NT64] SQL0104N An unexpected token "RENAME" was found following "D_HOLIDAY_LOG_OLD; ". Expected tokens may include: "TRUNCATE". LINE NUMBER=382. SQLSTATE=42601".
I suspect, its a syntax issue with the RENAME commands. If I need to add the whole query, I can. Thanks in advance
CREATE OR REPLACE PROCEDURE NSD_HOLIDAY_LOG_SPROC()
LANGUAGE SQL
SPECIFIC SP_NSD_HOLIDAY_LOG_SPROC
DYNAMIC RESULT SETS 1
BEGIN
COMMIT;
TRUNCATE TABLE TMWIN.NSD_HOLIDAY_LOG immediate;
DROP TABLE NSD_HOLIDAY_LOG_OLD;
RENAME TABLE TMWIN.NSD_HOLIDAY_LOG_LIVE TO NSD_HOLIDAY_LOG_OLD;
RENAME TABLE TMWIN.NSD_HOLIDAY_LOG TO NSD_HOLIDAY_LOG_LIVE;
RENAME TABLE TMWIN.NSD_HOLIDAY_LOG_OLD TO NSD_HOLIDAY_LOG;
END#
This is frequently asked.
As you are using static SQL in an SQL PL stored procedure, you must follow the documented rules for blocks of Compound SQL (Compiled) statements.
On of those rules is that static SQL has a restricted set of statements that can appear in such a block of code.
For example, with current versions of Db2-LUW, you cannot use any of the following statically (including rename table) :
ALTER , CONNECT,CREATE, DESCRIBE, DISCONNECT, DROP, FLUSH EVENT MONITOR, FREE LOCATOR, GRANT, REFRESH TABLE, RELEASE (connection only), RENAME TABLE, RENAME TABLESPACE, REVOKE, SET CONNECTION, SET INTEGRITY, SET PASSTHRU, SET SERVER OPTION ,TRANSFER OWNERSHIP
Other Db2 platforms (Z/OS, i-series) might have different restrictions but the same principle.
To achieve what you need you can use dynamic SQL instead of Static-SQL (as long as you understand the implications).
In other words, instead of writing:
RENAME TABLE TMWIN.NSD_HOLIDAY_LOG_LIVE TO NSD_HOLIDAY_LOG_OLD;
you could instead use:
execute immediate('RENAME TABLE TMWIN.NSD_HOLIDAY_LOG_LIVE TO NSD_HOLIDAY_LOG_OLD' );
or equivalent.
You can also use two statements, one to PREPARE and the other to EXECUTE , whichever suits the design. Refer to the documentation for execute immediate.
The same is true for other statements that your version of Db2 disallows in static compound-SQL (compiled) blocks (for example, DROP, or CREATE etc.).

Why alter command is referred as DDL and not DML?

I was going through the different commands in SQL and I came across alter command which is referred as DDL (Data Definition Language). We can alter the column and values in it, so we can manipulate the data with this command so why does alter command is not referred as DML (Data Manipulation Language).
I have googled and I can not come across some good explanation, so please help me with this.
ALTER command is used to alter the structure of the database. And this is what DDL does i.e., DDL statements are used to define the database structure or schema.
Whereas DML statement is used to manage data within schema objects.
DDL - alter the schema.
This including creating tables, renaming columns, dropping views, etc. Such statements are DDL even though such might create (default value), alter (by conversion), or even lose (removed column) data as part of the process. Basically, any CREATE/DROP/ALTER command is DDL.
DML - alter the information/data within the schema; without updating the schema.
This includes DELETE and UPDATE statements.
Sometimes DDL and DML must be used together to correctly migrate a schema; but they are two distinct categories of SQL commands, and DML never causes the schema to be changed.
Cause ALTER command is not manipulating the data. It is used to change a definition of o column or table or other DB objects.
See
http://www.w3schools.com/sql/sql_alter.asp
The "data" is the data in the tables defined by the user via DDL. The "metadata" is the data in the tables pre-defined by the DBMS that describe the tables (themselves and those defined by the user). So DML manipulates data in user tables or (usually only) reads metadata from system tables while DDL defines (CREATEs, ALTERs, DROPs) user tables and as a side effect updates metadata in system tables.
The ALTER command can be both DDL and DML. I have known ALTER to be DDL over the past just like the majority of those who have responded to this. However, with MySQL 5.7.x you will see that soon after initializing the database with mysqld --initialize --console a default root user account and its corresponding password is created. You can access your database with this newly created root user account BUT there is absolutely nothing that you can do after logging in. The only SQL statement allowed at this stage is the ALTER statement. This is used to change the default password generated during initialization. The syntax is ALTER USER 'root'#'localhost' IDENTITIED BY 'new_password'; . This is the only statement that the database accepts. This modifies/updates/manipulates the data (password) in the users table. In this regard I have concluded that the ALTER statement can be both DDL and DML

HSQLDB table not found using script to create table and insert data

I am using the GUI (hsqldb.jar) in HSQLDB 2.2.9 to create a DB. I have all the SQL commands in a separate text file. So to create the DB, I just copy the text and paste into the HSQLDB editor and hit the "Execute SQL" button. I have successfully created my DB several times with different revisions, each time executing the CREATE TABLE commands with one press of the "Execute SQL" button, and the INSERT INTO commands with a subsequent press of the "Execute SQL" button. This works, but it would be more convenient to execute both the CREATE and the INSERT commands at the same time. I've tried to combine these into one "Execute SQL", but I keep getting this error:
user lacks privilege or object not found: SHOP / Error Code: -5501 / State: 42501
Here's what I've tried:
CREATE TABLE Shop (
Id int NOT NULL IDENTITY,
Name varchar(255) NOT NULL,
UNIQUE (Name)
)
INSERT INTO Shop VALUES (
NULL,
'Test Shop'
)
Note that this exact same code works if I execute the SQL in two separate steps. I've tried putting COMMIT between the CREATE and the INSERT commands, as well as CHECKPOINT, but neither of these solved the problem. I also tried adding SET WRITE_DELAY FALSE at the top, but this didn't solve it either.
What do I need to add to this code to make it work in one step? Thanks!
This is not possible.
The GUI client sends all the text in the window to the database engine. The engine compiles all the statements before executing them. Because of this, if a statement relies on the completion of a previous statement, it won't compile.
The better way to populate your database from a script is the SqlFile tool which is part of SqlTool.jar. This tool executes statements one by one.
The separate Guide is here:
http://hsqldb.org/doc/2.0/util-guide/sqltool-chapt.html

SQL drop table and re-create and keep data

On our original design we screwed up a foreign key constraint in our table. Now that the table is full of data we cannot change it without dropping all of the records in the table. The only solution I could think of is to create a backup table and put all of the records in there, then delete all the records, alter the table and start adding them back. Any other (BETTER) ideas? Thanks!
Using MS SQL Server
I'm a bit late, just for reference.
If You are using SQL Server Management Studio, You could generate a DROP and RECREATE script with "Keep schema and data" option.
Right click on the desired DB in object explorer
Tasks > Generate scripts
Select the table you want to script
Then clicking on Advanced button
"Script DROP and CREATE" ->"Script DROP and CREATE"
"Types of data to script" -> "Schema and data"
Hope this helps
Here's some pseudo-code. No need to make a backup table, just make a new table with the right constraint, insert your records into it, and rename.
CREATE TABLE MyTable_2
(...field definitions)
<add the constraint to MyTable_2>
INSERT INTO MyTable_2 (fields)
SELECT fields
FROM MyTable
DROP TABLE MyTable
exec sp_rename 'MyTable2', 'Mytable'
Using SQL Server Management Studio (SSMS), you can use it's table designer to specify the final condition of the table. Before saving the changes, have it generate the change script and save that script. Cancel out of the design window, open the script and review it. SSMS may already have generated a script that does everything you need, fixing the primary-foreign key relationship while preserving all existing data. If not, you will have a script, already started, that performs most of what you need to do and should be able to modify it for your needs.
This is your only solution.
Create the backup table, empty the original one, modify the table and then insert step-by-step until you find a violation.
Update All Schema Database Old by new Schema Database .
Create script (Right click on the desired DB in object explorer Tasks > Generate scripts -> select option select specific database objects and tables ->next -> advanced-> option Type of data to script Data only -> ok ->next ->next.) to data only and backup Database to old database
Drop database old and create new database and make new DB is empty .
Excute script of Old Data only on new database .

SQL - create database and tables in one script

Sorry if already asked, but I can't find anything on this.
I am moving something over from MySQL to SQL Server I want to have a .sql file create a database and tables within the database. After working out syntax kinks I have gotten the files to work (almost).
If I run
IF db_id('dbname') IS NULL
CREATE DATABASE dbname
it works fine, and if I run
CREATE TABLE dbname.dbo.TABLE1 (
);
...
CREATE TABLE dbname.dbo.TABLEN (
);
it also works fine. But, if I run them in the same file I get this error
Database 'dbname' does not exist
Right now, the CREATE TABLE statements are not within the IF statement, which I would like, but I also cannot seem to find the syntax for that. ( { } does not work?)
So my big question is, how do I ensure a particular command in a .sql file is completed before another in SQL Server?
My second question is, how do I include multiple instructions within an IF clause?
To be clear, I have been running this into sqlcmd.
Put a GO command between queries.
IF db_id('dbname') IS NULL
CREATE DATABASE dbname
GO
CREATE TABLE dbname.dbo.TABLE1 (
);
CREATE TABLE dbname.dbo.TABLEN (
);
As for putting the table statements in the IF, you wouldn't be able to because of the GO command. You could create additional IF statements afterwards, to check for each tables pre-existence.
The syntax for a block if is:
IF condition
BEGIN
....
....
END
Between creating the database and creating the tables you will need a USE statement.
USE dbname
This way the tables will be created in the correct place, without having to specify the DB name on everything.
Also, GO and BEGIN...END like everyone else is saying.
You have to separate the statements with the GO keyword:
sql query
GO
another sql query
GO
and so on
By placing a GO between statements (to create separate batches of statements)