I have a number of Oracle triggers stored in a file which we upload to our DB using sqlplus. We want to use liquibase instead to manage this, but I don't really want to split out the triggers into separate files. The file looks like:
create or replace trigger Trig1 ...
...
end Trig1;
/
create or replace trigger Trig2 ...
...
end Trig2;
/
...etc.
I've tried
<sqlFile splitStatements="true" endDelimiter="/" path="triggers.sql">
but it still seems to be trying to split on ';'. If I change splitStatements to false. it then ignores the '/' and includes everything as an invalid single trigger.
Any ideas?
TIA.
I realize this is an old issue and OP has moved on, but for anyone else I ended up finding the answer here: http://forum.liquibase.org/topic/oracle-end-delimiter-issue.
It turns out "endDelimiter" is a regular expression -- this string should be used:
\n/\s*\n|\n/\s*$
I recently got this issue. endDelimiter should be:
endDelimiter="(?m)^/$"
I have a similar problem with Oracle 11g and Liquibase. I get an ORA-00911.
In my db-changelog.xml I point to a sql file where I have triggers. This does not work at all. I have tested the things you said above with /\;
CREATE OR REPLACE TRIGGER ADRESSE_ID_TR
BEFORE INSERT ON ADRESSE
FOR EACH ROW
WHEN (new.ID IS NULL) BEGIN
SELECT adresse_seq.NEXTVAL
INTO :new.ID
FROM dual;
END ADRESSE_ID_TR;\
My workaround is adding a in in db-changelog.xml.
I don't like it because the db-changelog.xml is going to be very large and I want it in the .sql files not in db-changelog.xml.
Another problem is when I generate DDL's with tools like Oracle SQL Developer and paste them in, they don't work. A lot of sql's don't work, probably not supported. I spend a lot of time testing my SQL's and Liquibase with Eclipse to fix the SQL's.
Any tips or will you fix this?
That syntax looks correct. The endDelimiter should be telling it to override the default ; delimiter and use / instead. What version of liquibase are you using? Does it help if you put the \ not by itself?
create or replace trigger Trig1 ...
...
end Trig1; /
create or replace trigger Trig2 ...
...
end Trig2; /
...etc.
Related
I am looking for a way to avoid a recurrent error of mine, working with SQL scripts that sometimes contain PL/SQL blocks. As you may know, in sqlplus, if you do not add a slash / after a PL/SQL block (Begin ... End;), the block is not executed.
But from my development tools, the lack of slash is not detected until my stuff gets deployed on the testing environment, and it adds confusion and stress to the process.
I had this issue in many places I've worked at, and with many tools. So I wonder if it is possible to configure Oracle sqlplus either to
execute the content of the "buffer" before commits, even if no / is there
raise an error message if "buffer" is not empty when exiting
Another solution would be to change the behaviour of my development tools, I know, but am also looking forward to extend my Oracle knowledge with your permission.
To fix the idea, let's say I deliver script a.sql, that is encapsulated later on into the company's deployment script dpl.sql
dpl.sql simplified (note the importance of the . that kind of hides the issue, but that I cannot change, and is THE thing to work around)
spool dpl.log
#a
.
spool off
a.sql where I forgot the / after my pl/Sql block before of personal inconsistency by design (beauty of Nature)
create table a(n number);
begin
dbms_output.put_line('coucou');
end;
insert into a select 1 from dual ;
commit ;
Result where you see no commit, and no error...
SQL> #dpl
Table dropped.
Table created.
SQL> select count(1) from a ;
COUNT(1)
----------
0
I went through these, to no avail:
When do I need to use a semicolon vs a slash in Oracle SQL?
oracle SQL plus how to end command in SQL file?
Hello and thanks in advance. I am running Oracle 11gR2 and want to try to execute an sql loader to insert data into an existing table. I am attempting this via Java stored proc in the database that will perform commands on the OS. The problem I am having is that I cannot seem to get the call to invoke SQLLDR.EXE to work - error I have is: sqlldr not found (NOTE that lookup with PATH isnt done due to the Oracle executable being SETUID)
----------------------Sample Code------------------------------------------
declare
l_ldr varchar2(1000) := '/u01/app/oracle/product/db/11.2.0.4/bin/sqlldr.exe control=C:\ad\controlfile.ctl, log=load.log, bad=load.bad,data=C:\somefile.txt';
l_env varchar2(1000) := 'PATH=/bin:/u01/oracle/db/11.2.0.4/jdk/bin;';
l_out varchar2(5000);
l_ret varchar2(5000);
begin
dbms_output.put_line(l_ldr);
MSO_Java.dbcmd('sqlldr.exe',
l_ldr,
l_env,
'Y',
l_out,
l_ret);
dbms_output.put_line(l_ret);
dbms_output.put_line(l_out);
end;
--------------------------END CODE SAMPLE--------------------
Appreciate ANY help here. I know this can be done.....
SQLLDR doesn't have the option to be executed in a PL/SQL, but you can simulate a SQLLDR with PL/SQL.
Yeap this is posible, I created a stored procedure that works fine just with REGEXP, now the documentation is in spanish but as soon that I can I will translate this.
Here is the link
Performence? Yeah I now that simulate a SQLLDR will be affect the performance in the database but NO, is this the reason that I used REGEXP. That works fine for me loading masive data.
Another thing is that this PL/SQL gives you the opportunity to transform the data. You can use a ETL for that but sometimes that is not possible :(.
THAT IS EASY TO UNDERSTAND :D!
I want to run sql like:
CREATE TEMPORARY TABLE tmptable AS SELECT * FROM redshift_table WHERE date > #{date};
I can run this sql in command line in Redshift, but if I run it in my program, it doesn't work correctly. When I change CREATE TEMPORARY TABLE to CREATE TABLE it works correctly.
I am using mybatis as OR mapper and driver is:
org.postgresql.Driver
org.postgresql:postgresql:9.3-1102-jdbc41
What's wrong?
I am assuming the #date is an actual date in your actual query.
Having said that, there is not reason this command doesnt work, its as per the syntax listed here,
http://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_AS.html
Have you tried posting it on AWS Redshift forums, generally they are quite responsive. Please update this thread too if you find something, this is quite an interesting issue, thanks!
I was trying to do something like auto-increment in Oracle 11g Express and SQL Developer.
I know very little about Oracle and I am also new to triggers.
I tried running this, but I don't know how to do it properly.
CREATE TABLE theschema.thetable
(id NUMBER PRIMARY KEY,
name VARCHAR2(30));
CREATE SEQUENCE theschema.test1_sequence
START WITH 1
INCREMENT BY 1;
create or replace trigger insert_nums
before insert on theschema.thetable
for each row
begin
select test1_sequence.nextval into :new.id from dual;
end;
/
When I try to create the trigger, I get a screen which asks me for some "binds".
The dialog box has only one check box "null". What does this mean and how do I make
a script that works properly?
Any precautions to take while doing this kind of "auto-increment" ?
It seems that SQL Developer thinks that you are running a plain DML (data manipulation) script, not a DDL (data definition). It also thinks that :new.id is a bindable variable.
Why this happens, I don't know; I can't reproduce it in Oracle SQL Developer 2.1.
Try to open a new SQL worksheet window in the theschema schema and execute a "whole" script (not a statement) by pressing F5 (not F9).
This is how I have solved this problem, put "set define off;" before the command:
set define off;
create or replace trigger [...]
[...]
end;
/
Then highlight both commands and press F9 to run.
Or you could run all the commands with F5.
It seems, that if the commands are executed separetly with F9, then the set define off does not take affect.
For my case, solution was entering "newrow" for 'new' and "oldrow" for 'old' as values for the binds...
I am a novice at this so keep that in mind as I give my answer.
I think the issue is that the code
create or replace trigger insert_nums
before insert on theschema.thetable
for each row
begin
select test1_sequence.nextval into :new.id from dual;
end;
Is actually a script and not straight forward SQL statement. Hence you have to run the "Run Script". I discovered that when I had a worksheet open in SQL Developer that if I had anywhere in the worksheet the any code for trigger like above then even I just tried to run a statement that SQL Developer would look back in the worksheet and try to run the script. To stop that from happening I had to comment out the code.
And If I did want to run the code for the trigger than I had to open a new worksheet, place the code there and do a RUN SCRIPT.
I'm trying to convert some Informix ESQL to Oracle Pro*C. In the existing Informix code the "SERIAL" data type was used to indicate automatically incrementing columns. According to the Oracle documentation, the Oracle Migration Workbench for Informix should be able to handle this, and it explains that it converts the "SERIAL" data type into a "NUMBER" with an associated Oracle sequence and trigger. However, when trying to run the tool it simply replaces the word "SERIAL" with "ERROR(SERIAL)", so I've been trying to manually add in the trigger/sequence.
Their example here: http://docs.oracle.com/html/B16022_01/ch2.htm#sthref112 shows a way that this can be done. The sequence appears to be fairly straight forward, however when trying to create a trigger like so:
CREATE TRIGGER clerk.TR_SEQ_11_1
BEFORE INSERT ON clerk.JOBS FOR EACH ROW
BEGIN
SELECT clerk.SEQ_11_1.nextval INTO :new.JOB_ID FROM dual; END;
The Pro*C preprocessor picks up the "CREATE" keyword here, and decides that I'm not allowed to use the host variable ":new.JOB_ID", because host variables cannot be used in conjunction with "CREATE" statements.
My question is, is there some way to create a trigger that links an Oracle sequence to a particular column without using a host variable to specify the column name? The Oracle documentation seems to indicate that their migration tool should be able to cope, which means there must be some way of doing this. However all the examples of the trigger use that I have found all use the host variable which causes the preprocessor to complain.
Thank you for your time.
(Note: I've used the trigger/sequence/column names from the example in the Oracle documentation in the example above.)
I managed to resolve the issue by using an "EXEC SQL EXECUTE IMMEDIATE" statement.
char sql_buf[4096+1];
snprintf(sql_buf, 4096, <sql>);
EXEC SQL IMMEDIATE :sql_buf;
This bypasses the preprocessor and therefore allows the statement through without complaint.
It is impossible to create a trigger that links an Oracle sequence to a particular column without using a "host variable" to specify the column name. By the way it isn't "host variable" - just reference. The same trigger may fire on update and insert for example, so you have to specify what you are referencing: new or old variables. You can do it in MS-SQL but not in Oracle.