PostgreSQL function : relation does not exist error - java

I am getting below error while calling Postgresql function with argument containing dot (.) operator.
SQL Error [42P01]: ERROR: relation "es.article_data" does not exist Where: PL/pgSQL function es.getrowcount(text) line 6 at EXECUTE....
Query: select es.getrowcount(schemawithtable :='es.article_data');
Function:
CREATE FUNCTION es.getrowcount (schemawithtable text)
RETURNS VARCHAR(50) AS $msg$
declare
msg VARCHAR(50);
total integer;
begin
execute format('select count(*) from %I where until_ts is null', schemawithtable) into total;
msg := CONCAT(total, ' records are there in ',schemawithtable);
RETURN msg;
END;
$msg$ LANGUAGE plpgsql;
Error traces from DBeaver:
org.jkiss.dbeaver.model.sql.DBSQLException: SQL Error [42P01]: ERROR: relation "es.article_data" does not exist
Where: PL/pgSQL function es.getrowcount(text) line 6 at EXECUTE
at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.executeStatement(JDBCStatementImpl.java:134)
at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.executeStatement(SQLQueryJob.java:487)
at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.lambda$0(SQLQueryJob.java:424)
at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:164)
at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.executeSingleQuery(SQLQueryJob.java:416)
at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.extractData(SQLQueryJob.java:774)
at org.jkiss.dbeaver.ui.editors.sql.SQLEditor$QueryResultsContainer.readData(SQLEditor.java:2914)
at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.lambda$0(ResultSetJobDataRead.java:110)
at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:164)
at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.run(ResultSetJobDataRead.java:108)
at org.jkiss.dbeaver.ui.controls.resultset.ResultSetViewer$17.run(ResultSetViewer.java:3421)
at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:103)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.postgresql.util.PSQLException: ERROR: relation "es.article_data" does not exist
Where: PL/pgSQL function es.getrowcount(text) line 6 at EXECUTE
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2183)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:308)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:307)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:293)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:270)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:266)
at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.execute(JDBCStatementImpl.java:338)
at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.executeStatement(JDBCStatementImpl.java:131)
... 12 more
I have figure out the workaround by passing schema name separately.
Working Query: select es.getrowcount(schemaname :='es',tablename :='article_data');
CREATE FUNCTION es.getrowcount (schemaname text, tablename text)
...
begin
execute format('select count(*) from %I.%I where until_ts is null',schemaname, tablename) into total;
...
$msg$ LANGUAGE plpgsql;
Versions:
PostgreSQL - 10.12
DBeaver (client) - 6.3.5
But I want to know why it is giving an error for argument containing dot (.) operator ?

When you are creating your query with format and %I. It is creating your query like below
With Single Parameter:
select count(*) from "es.article_data" where until_ts is null
With Double Parameter:
select count(*) from "es"."article_data" where until_ts is null
In first case it will show error because you can not use table name with schema like this. But in second case it worked perfectly as this is the right way to use naming convention.
If you want to use the first method only. you should use %s instead of %Ilike below
CREATE FUNCTION es.getrowcount (schemawithtable text)
RETURNS VARCHAR(50) AS $msg$
declare
msg VARCHAR(50);
total integer;
begin
execute format('select count(*) from %s where until_ts is null', schemawithtable) into total;
msg := CONCAT(total, ' records are there in ',tablename);
RETURN msg;
END;
$msg$ LANGUAGE plpgsql;
NOTE : This will work properly if your table names and schema names are in lower case only

Related

iBatis' ScriptRunner Is Failing To Execute a Perfectly Valid SQL Script

I'm using iBatis' ScriptRunner to execute scripts on an Oracle database. The first script is executed fine, but the second one which has triggers in it returns:
Cause: java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement
The part of the script which returns this error is executed without any errors on SQL Developer:
.
.
.
create table MG_MSGALR
(
ID VARCHAR2(30) not null,
V_GRAV VARCHAR2(3),
constraint PK_MG_MSGALR primary key (ID) using index tablespace B_INDEX
);
CREATE OR REPLACE TRIGGER UC_JAR_LST_TRIGGER
BEFORE INSERT
ON UC_JAR_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_JAR_LST_SEQ.nextval INTO :NEW.ID FROM dual;
END;
/
CREATE OR REPLACE TRIGGER UC_UPD_LST_TRIGGER
BEFORE INSERT
ON UC_UPD_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_UPD_LST_SEQ.nextval INTO :NEW.ID FROM dual;
END;
/
Here's how I execute the script from my side:
Boolean procedure = StringUtils.endsWith(FilenameUtils.getBaseName(file.getName()), "procedure") || StringUtils.endsWith(FilenameUtils.getBaseName(file.getName()), "trigger");
runner.setSendFullScript(procedure);
runner.runScript(new FileReader(file));
I noticed that the Boolean procedure's value is always false even when the script has triggers in it, and so I tried to force ScriptRunner to send it as a full script just to see if it goes through or not and i got the following error instead:
CREATE OR REPLACE TRIGGER UC_UPD_LST_TRIGGER
BEFORE INSERT
ON UC_UPD_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_UPD_LST_SEQ.nextval INTO :NEW.ID FROM dual;
END;
/
. Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
Could somebody please tell me what am I doing wrong here? Should add some sort of delimiter in the file right before when the trigger creation is supposed to start (which is now at the very end of the file).
In case someone else runs into the same problem. When you have a hybrid script (which means it has both normal queries and procedures or triggers), and if you're trying to execute it using myBatis from Java, all you need to do is leave all of your procedures at the end of your script and put delimiters before and after them to let SQL know it should be executed as a block and not line by line. So here's how I added my delimiters:
-- Change the delimiter to '$'
-- #DELIMITER $
CREATE OR REPLACE TRIGGER UC_JAR_LST_TRIGGER
BEFORE INSERT
ON UC_JAR_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_JAR_LST_SEQ.nextval INTO :NEW.ID FROM dual;
-- Change the delimiter back to ';'
-- #DELIMITER ;
END;
-- Change the delimiter to '$'
-- #DELIMITER $
CREATE OR REPLACE TRIGGER UC_UPD_LST_TRIGGER
BEFORE INSERT
ON UC_UPD_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_UPD_LST_SEQ.nextval INTO :NEW.ID FROM dual;
-- Change the delimiter back to ';'
-- #DELIMITER ;
END;
And the execution ended without errors.

How to import SQL function in Hibernate

I use Hibernate and Postgres.
I'm working on completely new project so it's convenient for me to delegate database creation to Hibernate and just verifying it's structure if needed.
During my development I configured hibernate to always delete and create tables when the app starts. I use import.sql to load initial data. I'd like to create a function in postgres.:
CREATE OR REPLACE FUNCTION someFunction() RETURNS boolean AS $$
BEGIN
RETURN (SELECT count(*) > 0 FROM user);
END; $$
LANGUAGE PLPGSQL;
I'd like this to be imported by Hibernate on startup.
However hibernate is not able to handle it due to this: $$
Caused by: org.postgresql.util.PSQLException: Unterminated dollar quote started at position 61 in SQL CREATE OR REPLACE FUNCTION someFunction() RETURNS boolean AS $$
BEGIN
RETURN (SELECT count(*) > 0 FROM user). Expected terminating $$
How can I make it work?

postgresql, Insert data into dynamically created table

I have to copy data from one table(main_tbl) to another table(sub_tbl)
CREATE OR REPLACE FUNCTION auditlogfunc() RETURNS TRIGGER AS
$example_table$
DECLARE
temp text;
BEGIN
temp = 'SELECT device_id FROM company ORDER BY id DESC LIMIT 1';
INSERT INTO temp(emp_id, entry_date, name,age) VALUES(new.id,current_timestamp, new.name, new.age);
RETURN NEW;
END;
$example_table$ LANGUAGE plpgsql;
temp = 'SELECT device_id FROM company ORDER BY id DESC LIMIT 1'; this will select the last value from main_tbl and stored into temp variable.
Now I want to copy data from main_tbl to temp table..
ERROR: relation "temp" does not exist
#a_horse_with_no_name has already pointed out how to do this. If i understood correctly, you dv002 table is already created.
CREATE OR REPLACE FUNCTION auditlogfunc ()
RETURNS trigger AS
$body$
DECLARE
get_last_value integer;
your_table_name text := 'dv002';
BEGIN
SELECT id into get_last_value FROM tb_main_table ORDER BY id DESC LIMIT 1;
EXECUTE format('insert into %s(emp_id, entry_date, name,age) VALUES ($1,$2,$3,$4,$5)', your_table_name) using get_last_value,new.id,current_timestamp, new.name, new.age;
RETURN new;
$body$
LANGUAGE plpgsql;
See here how to store the result of a query in a variable.
See here how to execute a string as an SQL command.
Use the quote_ident() function on the variable before including it as identifier in an SQL query string. That way you are safe from SQL injection.

SQL Exception: ORA-00936: missing expression

I am running following query:
my query = insert into tbl_name (ID,name, address,...)" +" values (?,?,?)
then I am using query runner class to insert.
myQueryRunnerObj.insert("my query",
result set handler obj,
generated id,
'my name',
'my address',...);
After this I am getting following exception: Exception in thread "main" java.sql.SQLException: ORA-00936: missing expression and sometimes invalid number of arguments expecting 11 given 10
What could be the reason to get this exception?
Correct syntax is:
INSERT INTO dept (deptno, dname) VALUES (dept_seq.nextval, 1);
or
INSERT INTO dept (deptno, dname)
SELECT dept_seq.nextval, 2
FROM dual;
ORA-00936: missing expression
Cause: A required part of a clause or expression has been omitted. For example, a SELECT statement may have been entered without a list of columns or expressions or with an incomplete expression. This message is also issued in cases where a reserved word is misused, as in SELECT TABLE.
Action: Check the statement syntax and specify the missing component.
check this

execute anonymous pl/sql block file with values from java

I have an anonymous pl/sql block in an sql file and I want to execute and assign values to it in Java. My sql block looks like this
DECLARE
someInput1 NUMBER(1);
someInput2 NUMBER(2);
someString1 VARCHAR(100);
BEGIN
someInput1 := ‘&1’;
someInput2 := ‘&2’;
--get name in table A
BEGIN
SELECT a.value INTO someString1
FROM TABLE_A a
WHERE a.id = someInput1;
END;
UPDATE TABLE_B b
SET b.someStringRow = someString1
WHERE b.someIntRow = someInput2;
COMMIT;
END;
/
exit;
What I am planning to do is load the sql file in a Java String, change ‘&1’ to ?1 and execute it as a CallableStatement. However, I am getting
PLS-00103: Encountered the symbol “” when expecting one of the following
begin function package pragma procedure subtype us <an identifier> <a double quoted delimited identifier> form current cursor
Error occured at lines in DECLARE section
Is my approach an acceptable solution, if yes, what may be wrong in my approach?
Are there other better solution for my problem? Thanks
you have to remove quote marks, and replace &1 with :1, and you should be fine, also, you will need remove '/' and exit; and they relate to sqlplus and not to pl/sql directly

Categories

Resources