Flyway callbacks with Oracle compile - oracle

I try to add before migration and after migration scripts as callbacks to flyway for compiling my views, procedures, functions etc.
Is there a possibility to stop it before a migration process or have a rollback when before or after scripts fail (or rather return a warning)?
Cause the only thing I see right now is I receive warnings like this
[WARNING] DB: Warning: execution completed with warning (SQL State: 99999 - Error Code: 17110)
and it goes on, without stopping.
I thought about FlywayCallback interface and it's implementation but I'm not entirely sure how it should be done with compiling.
I'm using Spring Boot 1.2.5 with the newest Flyway.

I have also same error. SQL State: 99999 - Error Code: 17110. i found this solution.
check which version under this warning and that version under sql script check have Trigger or any procedure which not closed properly.
close trigger or any procedure if oracle DB / end of trigger.
ex:
CREATE OR REPLACE TRIGGER Print_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON Emp_tab
FOR EACH ROW
WHEN (new.Empno > 0)
DECLARE
sal_diff number;
BEGIN
sal_diff := :new.sal - :old.sal;
dbms_output.put('Old salary: ' || :old.sal);
dbms_output.put(' New salary: ' || :new.sal);
dbms_output.put_line(' Difference ' || sal_diff);
END;
/

Flyway 5.0 now comes with a feature called Error Handlers that lets you do exactly this. You can now create an error handler that turns that warning into an error as simply as
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.errorhandler.Context;
import org.flywaydb.core.api.errorhandler.ErrorHandler;
import org.flywaydb.core.api.errorhandler.Warning;
public class OracleProcedureFailFastErrorHandler implements ErrorHandler {
#Override
public boolean handle(Context context) {
for (Warning warning : context.getWarnings()) {
if ("99999".equals(warning.getState()) && warning.getCode() == 17110) {
throw new FlywayException("Compilation failed");
}
}
return false;
}
}
More info in the docs: https://flywaydb.org/documentation/errorhandlers

I had the same error when my scripts had a "CREATE TABLE XXX AS SELECT..." statement.
I fixed it by splitting it into two separate statements:
CREATE TABLE XXX (columns def...);
INSERT INTO TABLE XXX (columns...)
SELECT...;

Related

Write custom H2 DB function Java

I am trying to run the below code using H2DB (via junit test), while doing so i get error message as below. I understand that, there are no function available as "days" in H2. So i am trying to write a custom function, but it does not work out, can any one help on writing this function.
SQLBuilder class code:
public String dummy() {
return new StringBuilder(new SQL() {
{
SELECT("date(CREATE_TMS)");
SELECT("CASE WHEN date(CREATE_TMS) >= (CURRENT DATE - cast('1' AS integer) days) THEN 'Y' ELSE 'N' END NEW_B");
FROM("Q.DUMMY");
}
}.toString().concat(" FOR READ ONLY WITH UR")).toString();
}
Error message:
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "SELECT DATE(CREATE_TMS), CASE WHEN DATE(CREATE_TMS) >= (CURRENT DATE - CAST('1' AS INTEGER) DAYS[*]) THEN 'Y' ELSE 'N' END NEW_BILLING
FROM Q.DUMMY FOR READ ONLY WITH UR "; expected "[, ::, *, /, %, +, -, ||, ~, !~, NOT, LIKE, ILIKE, REGEXP, IS, IN, BETWEEN, AND, OR, ,, )"; SQL statement:
SELECT date(CREATE_TMS), CASE WHEN date(CREATE_TMS) >= (CURRENT DATE - cast('1' AS integer) days) THEN 'Y' ELSE 'N' END NEW_BILLING
FROM Q.DUMMY FOR READ ONLY WITH UR [42001-199]
For some reason days are converted to DAYS[*], we can see that in error message.
Customer method i tried in schema-db2.sql:
drop ALIAS if exists days;
CREATE ALIAS days as '
import java.lang.String;
#CODE
java.lang.String days() throws Exception {
return "days";
}
';
applicaiton.properties:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;Mode=DB2
DAYS is not a function and is not a something that other databases support. Db2 also uses non-standard interval literals.
If you can build H2 from its current sources, you can use cast('1' AS integer) day in it (not the days) and such construction is also supported by Db2. You can also simply use 1 DAY, it is supported by current H2 and Db2 too.
(CURRENT_DAY - 1 DAY)
Sources of H2 are available on GitHub:
https://github.com/h2database/h2database
Building instructions are here:
https://h2database.com/html/build.html#building
You need a jar target.
To compile H2 from the current sources you need JDK 8, 9, 10, 11, or 12. Compiled jar will be compatible with more recent versions.

"Commands out of sync" error when trying to execute a procedure in MySQL 8

When executing below code in phpMyAdmin:
use db;
DELIMITER $$
DROP PROCEDURE IF EXISTS McaTest3$$
CREATE PROCEDURE McaTest3()
BEGIN
SELECT
cl.*
FROM `condition_library` cl
LEFT JOIN condition_custom cc on cl.condition_library_id = cc.condition_library_id
and cc.active = 1
AND (cc.permit_application_id = 20231 OR cc.permit_id = NULL)
WHERE FIND_IN_SET(cl.`condition_library_id`, '13070')
AND cl.active = 1
and cc.condition_library_id IS NULL;
END$$
DELIMITER ;
call McaTest3();
Getting error:
Error
Static analysis:
1 errors were found during analysis.
Missing expression. (near "ON" at position 25)
SQL query: Edit Edit
SET FOREIGN_KEY_CHECKS = ON;
MySQL said: Documentation
#2014 - Commands out of sync; you can't run this command now
This happens when there is no record found in the table which is at LEFT JOIN.
When the same is ran in MySQL Workbench: NO ERROR and return empty dataset.
Same procedure when executed from Application (Appian) is failing as well… Any clues?
Another question on Stackoverflow answered my issue:
link: MySQL error #2014 - Commands out of sync; you can't run this command now

System.out.message in JAVA Source in Oracle

if we create a java source using below way in oracle
CREATE JAVA SOURCE NAMED "Welcome" AS
public class Welcome {
public static String welcome() {
System.out.println("Welcome "); }
}
/
Where can i see the message ?
Reason for Why I am asking for this Question is .
Right now I am debugging one Email Sending Application(Alerts). The application is working fine for the alerts doesnt have any attachment, but if there is any attachment I am getting Java call Terminated by uncaught Java Exception java.lang.NoClassDefFoundError
The application Flow is as below
PLSQL Package (Here we fetch all the data and call Java Source)
JAVA Source (XXABC_SENDMAIL.sendMail is use to send the mail)
When I put DBMS.output I can reach till the point where JAVA source call is happening , but i need to find , at exactly which place the JAVA error is getting thrown.
I got the EXACT answer from the below link..
http://blogs.dayneo.co.za/2012/11/simplest-way-to-debug-your-oracle-java.html
Direct from the Link
dayneo#RMSD> CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED SimpleSample as
2 public class SimpleSample
3 {
4 public static void simplemsg()
5 {
6 System.out.println(new java.util.Date().toString() + ": Hello world!");
7 }
8 }
9 /
Java created.
dayneo#RMSD> create or replace procedure simplesample_says as
2 language java name 'SimpleSample.simplemsg()';
3 /
Procedure created.
dayneo#RMSD> set serveroutput on size 1000000
dayneo#RMSD> call dbms_java.set_output(1000000);
Call completed.
dayneo#RMSD> begin
2 simplesample_says();
3 end;
4 /
Mon Nov 05 15:37:03 GMT+02:00 2012: Hello world!
PL/SQL procedure successfully completed.
its more or less the same as the
Stack overflow question "where does system.out.println output goes in oracle java class"
but I feel the link fits 100% to my question.

Test the existence of a Teradata table and create the table if non-existent

Our Continuous Inegration server (Hudosn) is having a strange issue when attempting to run a simple create table statement in Teradata.
This statement tests the existence of the max_call table:
unless $teradata_connection.table_exists? :arm_custom_db__max_call_attempt_parameters
$teradata_connection.run('CREATE TABLE all_wkscratchpad_db.max_call_attempt_parameters AS (SELECT * FROM arm_custom_db.max_call_attempt_parameters ) WITH NO DATA')
end
The table_exists? method does the following:
def table_exists?(name)
v ||= false # only retry once
sch, table_name = schema_and_table(name)
name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
from(name).first
true
rescue DatabaseError => e
if e.to_s =~ /Operation not allowed for reason code "7" on table/ && v == false
# table probably needs reorg
reorg(name)
v = true
retry
end
false
end
So as per the from(name).first line, the test which this method is performing is just a simple select statement, which, in SQL, looks like: SELECT TOP 1 MAX(CAST(MAX_CALL_ATTEMPT_CNT AS BIGINT)) FROM ALL_WKSCRATCHPAD_DB.MAX_CALL_ATTEMPT_PARAMETERS
The above SQL statement executes perfectly fine within Teradata SQL Assistant, so it's not a SQL syntax issue. The generic ID which our testing suite (Rubymine) uses is also not the issue; that ID has select access to the arm_custom_db.
The exeption which I can see is being thrown (within the builds console output on Hudson) is
Sequel::DatabaseError: Java::ComTeradataJdbcJdbc_4Util::JDBCException. Since this execption is a subclass of DatabaseError, the exception shouldn't be the problem either.
Also: We use unless statements like this every day for hundreds of different tables, and all except this one work correctly. This statement just seems to be a problem.
The complete error message which appears in the builds console output of Hudson is as follows:
[2015-01-07T13:56:37.947000 #16702] ERROR -- : Java::ComTeradataJdbcJdbc_4Util::JDBCException: [Teradata Database] [TeraJDBC 13.10.00.17] [Error 3807] [SQLState 42S02] Object 'ALL_WKSCRATCHPAD_DB.MAX_CALL_ATTEMPT_PARAMETERS' does not exist.: SELECT TOP 1 MAX(CAST(MAX_CALL_ATTEMPT_CNT AS BIGINT)) FROM ALL_WKSCRATCHPAD_DB.MAX_CALL_ATTEMPT_PARAMETERS
Sequel::DatabaseError: Java::ComTeradataJdbcJdbc_4Util::JDBCException: [Teradata Database] [TeraJDBC 13.10.00.17] [Error 3807] [SQLState 42S02] Object 'ALL_WKSCRATCHPAD_DB.MAX_CALL_ATTEMPT_PARAMETERS' does not exist.
I don't understand why this specific bit of code is giving me issues...there does not appear to be anything special about this table or database, and all SQL code executes perfectly fine in Teradata when I am signed in with the same exact user ID that is being used to execute the code from Hudson.

How to create a user defined function in sybase?

I trying to define a function in sybase. I write this script:
CREATE FUNCTION GetUserGroup (userId int)
RETURNS int
BEGIN
RETURN (10)
END
but when I run this, I get this error:
>[Error] Script lines: 1-6 --------------------------
Incorrect syntax near the keyword 'BEGIN'.
Msg: 156, Level: 15, State: 2
Server: NEWSERVER, Procedure: GetUserGroup, Line: 3
>[Error] Script lines: 1-6 --------------------------
A RETURN statement with a return status may only be used in a SQL stored procedure.
Msg: 178, Level: 15, State: 1
Server: NEWSERVER, Procedure: GetUserGroup, Line: 4
[Executed: 10/13/09 11:01:29 AM IRST ] [Execution: 0/ms]
What can I do?
Thanks
I searched very much in web and other documents, I find that user-defined functions in Adaptive Server Enterprise 12 (ASE) must be implemented in Java.
I decided to use a StordProcedure. It usage is a little hard but it supported in all version of Sybase.
see: http://www.sypron.nl/udf.html
I doesn't find any thing wrong with the code. you can re-try with the code below-
CREATE FUNCTION GetUserGroup (userId int)
RETURNS int
As
BEGIN
RETURN (10)
END
Try This ....it will work
CREATE FUNCTION GetUserGroup (#userId int)
RETURNS int
As
BEGIN
declare #Result int
select #Result=10
RETURN #Result
END
this worked for me.
CREATE FUNCTION GetUserGroup (#userId int)
RETURNS int
AS
BEGIN
select #userId = 10
RETURN #userId
END

Resources