Liquibase doesn't execute SQLs and returns Update Successful - sql

I have created a new PostgreSQL DB on my PC,
CREATE DATABASE "Test_Liquibase_Versionin"
WITH OWNER = postgres
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'English_United States.1252'
LC_CTYPE = 'English_United States.1252'
CONNECTION LIMIT = -1;
Downloaded liquibase-3.4.2-bin and run this command:
C:\LiquiBase\liquibase.bat --driver=org.postgresql.Driver --classpath="C:\LiquiBase\Driver\postgresql-9.4.1212.jar" --changeLogFile=C:\LiquiBase\changes\databaseChangeLog.sql --url="jdbc:postgresql://localhost:5432/Test_Liquibase_Versionin?user=test&password=Password" update
Got this response Liquibase Update Successful
check the DB and notice that I have 2 tables databasechangelog, databasechangeloglock
changed databaseChangeLog.sql to look like this:
--liquibase formatted sql
create table employees( uuid int, name Varchar(10));
insert into employees values(1, 'Mr');
insert into employees values(2, 'Mail');
create table depts( dept_id int, dep_name Varchar(10));
executed again C:\LiquiBase\liquibase.bat.........
Got this response Liquibase Update Successful
Logged into my DB - but there are no new tables as expected.
What could be the reason for that? What could I do to test whats gone wrong?

You need to add a changeset to the script.
This is because you are telling Liquibase that your sql script is Liquibase formatted sql. But since you do not have any changeset in it, it does nothing.
--liquibase formatted sql
--changeSet PeterH:Inserting-Values1 endDelimiter:; splitStatements:true stripComments:false runOnChange:false
create table employees( uuid int, name Varchar(10));
insert into employees values(1, 'Mr');
insert into employees values(2, 'Mail');
create table depts( dept_id int, dep_name Varchar(10));

In my case, I was setting liquibase header on the file, but the problem was with an space between username (the user that makes the change) and the parameter:
--liquibase formatted sql
--changeset Jenkins: scriptname.sql stripComments:true splitStatements:true
As you can see, there is an space between "Jenkins:" and "scriptname.sql". I've deleted that space and it runs ok

Related

Postgres - upsert on passed parameter

In my project I am using Postgres 12 and I want to use one sql query to INSERT OR UPDATE..
My syntax is not correct.
UPDATE: Insert works but updating does not.
ERROR: Invalid parameter number: :name"
'INSERT INTO user (
name, url
) VALUES (:name, :url)
ON CONFLICT (id)
WHERE id = :userId
DO UPDATE SET
name = :name,
url = :url'
I am using this EXAMPLE to do UPSERT and I want to UPDATE if userId is passed and if not to INSERT new row.
Thanks
BEGIN;
CREATE TABLE users (
user_id bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
name text,
url text
);
INSERT INTO users (name, url)
VALUES ('Hello', 'world');
COMMIT;
using psql: https://www.postgresql.org/docs/current/app-psql.html
set variable in psql: How do you use script variables in psql?
You can also set variable in an transaction.
BEGIN;
\set name 'hi'
\set url 'yech'
INSERT INTO users (user_id, name, url)
VALUES (1, :'name', :'url')
ON CONFLICT (user_id)
DO UPDATE SET
name = EXCLUDED.name, url = EXCLUDED.url
RETURNING
*;
TABLE users;
COMMIT;

Python pyODBC : Issue inserting into a sql server table with an identity column

An INSERT statement that was created with Python gives me an error when I execute and commit it. I have taken a copy of the statement from Python and run it myself in SQL SERVER and it works fine there. The table I am trying to insert into has an identity column. When Python trys to execute it will give me an error saying what is below when I exclude the identity column in the statement
Table looks like this MY_TABLE ( ID INT IDENTITY(1,1) NOT NULL, A INT, B INT)
INSERT INTO MY_TABLE (A, B) VALUES(VALUE_A, VALUE_B);
"('23000', "[23000] [Microsoft][ODBC SQL Server Driver][SQL Server]Cannot insert the value NULL into column 'MY_IDENTITY_COLUMN', table 'MY_TABLE'; column does not allow nulls. INSERT fails. (515) (SQLExecDirectW); [23000] [Microsoft][ODBC SQL Server Driver][SQL Server]The statement has been terminated. (3621)")"
But when I try to include the value for the Identity column (I don't want to do this) I get the following error which makes sense as it's an identity column that we let the table auto-increment
"Cannot insert explicit value for identity column in table 'MY_TABLE' when IDENTITY_INSERT is set to OFF."
When I run the query in SQL SERVER the table fills the value for the Identity Column itself and auto-increments but for some reason when I run the statement in Python it does not do this and tries to pass a NULL
SQL SERVER version: 10.50.6560.0
Recognising it's a little late but... I had the same problem recently using some old program and ODBC. The solution was to create a View in SQL Server with only the columns required (i.e. A and B in your case) and then insert into that View.
A little hard to tell without your code, but here is an example.
In database create a test table
CREATE TABLE dbo.test(
ID INT IDENTITY NOT NULL PRIMARY KEY,
Name VARCHAR(40) NOT NULL
);
Then in Python specify the columns you are inserting into
import pyodbc
warecn = pyodbc.connect("Your Connection Stuff")
Inscursor = warecn.cursor()
Inscursor.execute("Insert into dbo.test(name) values ('This'), ('is'), ('a'), ('test')")
Inscursor.commit()
Inscursor.close()
del Inscursor
warecn.close()

Insert multiple records into table for each user in another table in SQL Server

I want to create notification application in node js and I just created a database with these three tables in SQL Server:
tbluser
user_id
user_name
tbluser_notification
user_id
noti_id
read
tblnotification
noti_id
noti_title
noti_mesg
noti_create
noti_sender_id
My question is: whenever I insert a notification into tblnotification, I want to insert a record for each user into the tbluser_notification.
Create after insert trigger
CREATE TRIGGER [dbo].[trgtblnotificationInsert]
ON [dbo].[tblnotification]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO tbluser_notification (user_id, noti_id, notificationread)
SELECT tbluser.user_id, inserted.noti_id, 0
FROM tbluser
CROSS JOIN inserted
END
Please note: I have changed the column name 'read' to 'notificationread' as read is reserved word.

Check Excel file destination temp table in SSIS?

I have created ssis package to generate excel file dynamically from sql table.
But when I try to check whether that excel connection temp table if present or not using below query in sql task it gets failed syntax error
IF object_id(MyExcel) is not null
CREATE TABLE `MyExcel` (
`CUSIP` varchar(50),
`FaceAmount` decimal(18,4),
`Portfolio` varchar(50),
`PositionDate` DateTime,
`PositionCost` decimal(18,6),
`CurrentPrice` decimal(18,6)
)
else drop table MyExcel
ERROR :
[Execute SQL Task] Error: Executing the query "IF object_id(MyExcel) is not null
CREATE TABLE `..." failed with the following error: "Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.
Please advise?
I have tried with answer
IF OBJECT_ID(N'MyExcel') IS NOT NULL
BEGIN
DROP TABLE MyExcel;
END;
CREATE TABLE [MyExcel]
(
[CUSIP] VARCHAR(50),
[FaceAmount] DECIMAL(18,4),
[Portfolio] VARCHAR(50),
[PositionDate] DATETIME,
[PositionCost] DECIMAL(18,6),
[CurrentPrice] DECIMAL(18,6)
);
But still getting same error for statements
IF OBJECT_ID(N'MyExcel') IS NOT NULL
BEGIN
DROP TABLE MyExcel;
END;
I'm using this query inside SQL TASK
Connection type is EXCEL
This appears to be a combination of SQL-Server syntax (OBJECT_ID('ObjectName')) and MySQL syntax (back ticks for object names). I am assuming you are connecting to a SQL-Server database so you should qualify your object names with []. e.g.
IF OBJECT_ID(N'MyExcel') IS NOT NULL
BEGIN
CREATE TABLE [MyExcel]
(
[CUSIP] VARCHAR(50),
[FaceAmount] DECIMAL(18,4),
[Portfolio] VARCHAR(50),
[PositionDate] DATETIME,
[PositionCost] DECIMAL(18,6),
[CurrentPrice] DECIMAL(18,6)
);
END;
ELSE
BEGIN
DROP TABLE MyExcel;
END;
However, I believe your logic is flawed, your statement is saying "If the table exists, create it, if not drop it", so if it does already exist you will get an error saying the table already exists, if it doesn't then you will get an error saying you can't drop it because it doesn't exist. What you would really want is:
IF OBJECT_ID(N'MyExcel') IS NULL
BEGIN
CREATE TABLE [MyExcel]
....
However, this still presents you with a problem, since if the table exists before the task is run, it won't after, if it doesn't exist before then it will be created, which means whether or not the table exists after the task completes is dependent on whether or not the table exists before. I would imagine you want to do something like:
IF OBJECT_ID(N'MyExcel') IS NULL
BEGIN
CREATE TABLE [MyExcel]
(
[CUSIP] VARCHAR(50),
[FaceAmount] DECIMAL(18,4),
[Portfolio] VARCHAR(50),
[PositionDate] DATETIME,
[PositionCost] DECIMAL(18,6),
[CurrentPrice] DECIMAL(18,6)
);
END;
ELSE
BEGIN
TRUNCATE TABLE [MyExcel];
-- If you don't want to truncate the table and want it with
-- it's previous data in just remove the entire `else` clause
END;
Or
IF OBJECT_ID(N'MyExcel') IS NOT NULL
BEGIN
DROP TABLE MyExcel;
END;
CREATE TABLE [MyExcel]
(
[CUSIP] VARCHAR(50),
[FaceAmount] DECIMAL(18,4),
[Portfolio] VARCHAR(50),
[PositionDate] DATETIME,
[PositionCost] DECIMAL(18,6),
[CurrentPrice] DECIMAL(18,6)
);
i.e. after the task is run you will always have an table called MyExcel in the database, so you know it will be there when you get to the next step in your SSIS package.
ADDENDUM
As far as I know, you cannot use IF with an excel connection. There is an article here on querying the meta data from an excel workbook so you can check if a table exists. This is probably the technically correct way of doing it.
I was able to create a work around though, by having an Execute SQL Task with the following SQL:
DELETE
FROM MyExcel;
Then adding another Execute SQL Task to the On Error event handler to run:
CREATE TABLE MyExcel
(
CUSIP VARCHAR(50),
FaceAmount DECIMAL(18,4),
Portfolio VARCHAR(50),
PositionDate DATETIME,
PositionCost DECIMAL(18,6),
CurrentPrice DECIMAL(18,6)
);
So if the table does not exists, the delete statement will throw an error, which will trigger the create table statement. Thus ensuring after the task has run the table MyExcel definitely exists.
These tasks could be reversed, the result would be the same
You don't create an excel file with CREATE TABLE. If you come to think of excel file as database, the tables would be.. worksheets :).
To create an excel file, you'd Excel Connection Manager. You need to point it once to a template file, and after you set up excel destination with correct expressions, the file will be created. If it already exists, you just need to redirect the error.
And then you use Execute Sql to create the table (i.e. worksheet), of your desired structure.
You can add a Execute SQL Task to the end of the control flow to Drop the Excel table(s) in the package. This will leave the environment ready for the package to be processed again.

Script stops working on HSQLDB 1.9.0-rc6

DROP VIEW V1 IF EXISTS;
DROP TABLE T1 IF EXISTS;
CREATE TABLE T1 (id INT, name VARCHAR(32), age int);
CREATE VIEW V1 AS (SELECT * FROM T1 WHERE age < 21);
I have no problem to execute the SQL statement above in one JDBC statement or on the SWING Manager from HSQLDB. Now it stops working on 1.9.0-rc6.
This is error message I got - "user lacks privilege or object not found: T1 / Error Code: -5501 / State: 42501"
Does anyone know what have changed in 1.9.0-XX which made it not working?
Thanks
In HSQLDB 1.9, it has changed to compile entire script instead of interpreting it line by line, so CREATE VIEW v1 will throw an error of not seeing T1 available.
The script has to be broken into 2 executions - first create table, then create view.
DROP TABLE T1 IF EXISTS;
CREATE TABLE T1 (id INT, name varchar(32));
INSERT INTO T1 VALUES(0, 'Eric');
INSERT INTO T1 VALUES(0, 'Tom');
The sql above will not work in one single JDBC statement anymore in 1.9.0-rc.