ERROR 1064 (42000):You have an error in your SQL syntax; near '' at line 15 - mysql-error-1064

I just want to create simple function in mysql 5.7 but getting below error ....
tried all possible ways ....but no luck....Please find the mistake.
Table :
select * from emp_tab;
+-------+---------+------+--------+
| empno | ename | sal | deptno |
+-------+---------+------+--------+
| 7101 | Martin | 4000 | 10 |
function syntax:
mysql> create function employeebonus(eno int(10))
-> returns double deterministic
-> begin
-> declare temp double;
-> declare bonus double;
-> select sal into temp from emp_tab where empno=eno;
-> if temp<=10000 then
-> set bonus=temp*0.10;
-> else if temp<=20000 then
-> set bonus=temp*0.20;
-> else
-> set bonus=temp*0.30;
-> end if;
-> return bonus;
-> end$$
at 15 th line , tried with another syntax
->end;
->$$
and
->end
->$$
but nothing got worked
ERROR 1064 (42000):You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 15

error in this line ...
else if temp<=20000 then
This line should be corrected as
elseif temp<=20000 then
no space between "else if" ...its "elseif"

Related

PL/SQL MERGE INTO statement ignored

I want to create procedure will move the product (isdiscontinued=1) to another table (Product_discontinued_[NTID]). Structure of the two tables is identical.
PROCEDURE move_table AS
begin
merge into PRODUCTS_DISCONTINUTED b
using PRODUCTS a
on (a.ID = b.ID)
when matched then
update set b.id = a.id,b.productname = a.productname,b.supplierid=a.supplierid,b.unitprice=a.unitprice,
b.package=a.package, b.isdiscontinuted=a.isdiscontinuted
where a.isdiscontinuted = 1
when not matched then
insert (id,productname,supplierid,unitprice,package,isdiscontinuted)
values( a.id,a.productname,a.supplierid,a.unitprice,a.package,a.isdiscontinuted)
where a.isdiscontinuted = 1; END move_table;
I tried to write a procedure to move table PRODUCTS_DISCONTINUTED to PRODUCTS with using MERGE INO statement but it always keep getting the following errors. Could you please help me. Much appreciated.
[enter image description here][2]
error
Terminate merge and remove null;
when not matched then
insert ...
where a.isdicontinuted = 1; --> semi-colon here
-- null; --> remove this
end move_table;
I created tables involved, simply by looking at code you posted. Doing so, procedure gets created:
SQL> CREATE OR REPLACE PROCEDURE move_table
2 AS
3 BEGIN
4 MERGE INTO PRODUCTS_DISCONTINUTED b
5 USING PRODUCTS a
6 ON (a.ID = b.ID)
7 WHEN MATCHED
8 THEN
9 UPDATE SET b.id = a.id,
10 b.productname = a.productname,
11 b.supplierid = a.supplierid,
12 b.unitprice = a.unitprice,
13 b.package = a.package,
14 b.isdiscontinuted = a.isdiscontinuted
15 WHERE a.isdiscontinuted = 1
16 WHEN NOT MATCHED
17 THEN
18 INSERT (id,
19 productname,
20 supplierid,
21 unitprice,
22 package,
23 isdiscontinuted)
24 VALUES (a.id,
25 a.productname,
26 a.supplierid,
27 a.unitprice,
28 a.package,
29 a.isdiscontinuted)
30 WHERE a.isdiscontinuted = 1;
31 END move_table;
32 /
Procedure created.
SQL>
However, error you specified:
ORA-00904: "ISDISCONTINUTED" invalid identifier
means that there's no column whose name is ISDISCONTINUTED. Are you sure you didn't make a typo? Compare table description to code in the procedure - I guess there's a mismatch.

Inconsistent error ORA-01722: invalid number

I got an error with the message "ORA-01722: invalid number" when I executed my query. As digged in, I found out, I will get that error when I use a numeric value for a column that expects a varchar.
In my case my query had a case statement like
CASE WHEN CHAR_COLUMN= 1 THEN 'SOME VALUE' END
But the behavior was different in different instances of same oracle version. The same query worked in one of our dev oracle server, but not in the other. I am curious if there is any configuration that allows oracle to use numeric value to be used in a character column.
PS: The oracle version that we are using is Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
I never rely on implicit data type conversion but always make it explicit:
CASE WHEN CHAR_COLUMN = TO_CHAR(1) THEN 'SOME VALUE' END
Or even not convert at all:
CASE WHEN CHAR_COLUMN = '1' THEN 'SOME VALUE' END
The reason is that Oracle tends to convert the character string to a number, not the other way round. See the example from the linked manual page:
Text Literal Example
The text literal '10' has data type CHAR. Oracle implicitly converts it to the NUMBER data type if it appears in a numeric expression as in the following statement:
SELECT salary + '10'
FROM employees;
To reproduce the issue:
create table foo (
CHAR_COLUMN varchar2(10)
);
create table bar (
CHAR_COLUMN varchar2(10)
);
insert into foo (CHAR_COLUMN) values ('1');
insert into foo (CHAR_COLUMN) values ('2');
insert into bar (CHAR_COLUMN) values ('1');
insert into bar (CHAR_COLUMN) values ('yellow');
Then, when querying against numeric 1, the first query table works and the second doesn't:
select * from foo where CHAR_COLUMN = 1;
select * from bar where CHAR_COLUMN = 1;
When you ask Oracle to resolve this comparison:
WHEN CHAR_COLUMN = 1
... Oracle converts the query internally to:
WHEN TO_NUMBER(CHAR_COLUMN) = 1
In my example, this can be spotted in the explain plan:
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 3 | 00:00:01 |
| * 1 | TABLE ACCESS FULL | FOO | 1 | 7 | 3 | 00:00:01 |
---------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - filter(TO_NUMBER("CHAR_COLUMN")=1)

oracle procedure looping a string and insert into another table

I have this string : RC1500ZQ10RC2400ZQ20RC23ZQ3RC2322ZQ22
I need to create a procedure or trigger to split the above string and then insert it as a rows to another tables . 
Like This :
RC = NEW ROW . 
ZQ = NEW COULMN .
Row 1 RC1500ZQ10 = 1500,10 
Row 2 RC2400ZQ20 = 2400,20
Row 3 RC23 ZQ3 = 23,3
Row 4 RC2322ZQ22 = 2322,22
and so on .. 
Can anyone help on this ?
Any specific reason why you need procedure or Trigger for this?.
Use REGEXP_SUBSTR with CONNECT BY in a single SQL. You may include the query in your procedure to perform insert by passing the string argument.
'RC(.+?)ZQ' - match anything between RC and next ZQ
'ZQ(.+?)(RC|$)' - match anything between ZQ and next RC or line end
SQL Fiddle
Oracle 11g R2 Schema Setup:
create table t as
select 'RC1500ZQ10RC2400ZQ20RC23ZQ3RC2322ZQ22' as s from dual;
Query 1:
--INSERT INTO yourtarget(rc,zq)
SELECT REGEXP_SUBSTR(s, 'RC(.+?)ZQ', 1, LEVEL, NULL, 1) AS RC,
REGEXP_SUBSTR(s, 'ZQ(.+?)(RC|$)', 1, LEVEL, NULL, 1) AS ZQ
FROM t --or DUAL
CONNECT BY LEVEL <= REGEXP_COUNT(s, 'RC(.+?)ZQ')
Results:
| RC | ZQ |
|------|----|
| 1500 | 10 |
| 2400 | 20 |
| 23 | 3 |
| 2322 | 22 |

Issue with WHILE loop in PSQL shell

I'm trying to use a WHILE LOOP to insert columns from a collection of tables in PSQL shell. Code is as follows:
\set start_id 909
\set end_iter 912
-- Create base table to be later inserted
DROP TABLE IF EXISTS t_base_table;
CREATE TEMP TABLE t_base_table (
...
)
DISTRIBUTED RANDOMLY;
SELECT :start_id AS iter \gset
BEGIN
WHILE :iter <= :end_iter LOOP
\set weekly 'table_i_want_col_from_':iter
INSERT INTO t_base_table
SELECT ... --same columns as in the base table
FROM :weekly a
GROUP BY 1,2,3,4,5,6
SELECT :iter+1 AS iter \gset
END LOOP;
END;
I got several error messages:
ERROR: syntax error at or near "WHILE" LINE 2: WHILE 909 <= 912 LOOP
ERROR: syntax error at or near "SELECT" LINE 13: SELECT 909+1 AS week_id
ERROR: syntax error at or near "LOOP" LINE 1: END LOOP;
Looks like when I ran the script, it got split up in the psql shell (thus the 'LINE 1' in the item 3 above). I'm wondering is it because this syntax is not valid for psql shell? Or am I using the \set or \gset in a wrong way.
Thanks in advance for any help you may provide!!

How to use Oracle DBMS_ADVANCED_REWRITE with bind variable?

We need to implement a query rewrite with a bind variable because we don't have the option of modifying the web application source code. Example:
BEGIN
SYS.DBMS_ADVANCED_REWRITE.declare_rewrite_equivalence (
name => 'test_rewrite2',
source_stmt => 'select COUNT(*) from ViewX where columnA = :1',
destination_stmt => 'select COUNT(*) from ViewY where columnA = :1',
validate => FALSE,
rewrite_mode => 'recursive');
END;
The above command will result in error because there is a bind variable:
30353. 00000 - "expression not supported for query rewrite"
*Cause: The SELECT clause referenced UID, USER, ROWNUM, SYSDATE,
CURRENT_TIMESTAMP, MAXVALUE, a sequence number, a bind variable,
correlation variable, a set result, a trigger return variable, a
parallel table queue column, collection iterator, a non-deterministic
date format token RR, etc.
*Action: Remove the offending expression or disable the REWRITE option on
the materialized view.
I am reading here that there is a work around but I just cannot find the document anywhere online.
Could you please tell me what the work around is?
You can't specify the bind parameters, but it should already work as you wish. The key is the recursive parameter you passed as mode.
The recursive and general mode will intercept all statements that involve the table (or view), disregarding the filter, and transform them to target the second table (or view), adapting the filter condition from your original statement.
(If you had defined it as TEXT_MATCH, it would have checked the presence of the same filter in the original and target statement in order to trigger the transformation.)
In the example below one can see that even if we don't define any bind condition, the filter id = 2 is applied nervetheless; in other words it is actually transforming the SELECT * FROM A1 where id = 2 into SELECT * FROM A2 where id = 2
set LINESIZE 300
drop table A1;
drop view A2;
drop index A1_IDX;
EXEC SYS.DBMS_ADVANCED_REWRITE.drop_rewrite_equivalence (name => 'test_rewrite');
create table A1 (id number, name varchar2(20));
insert into A1 values(1, 'hello world');
insert into A1 values(2, 'hola mundo');
create index A1_IDX on A1(id);
select * from A1;
ALTER SESSION SET QUERY_REWRITE_INTEGRITY = TRUSTED;
CREATE OR REPLACE VIEW A2 AS
SELECT id,
INITCAP(name) AS name
FROM A1
ORDER BY id desc;
BEGIN
SYS.DBMS_ADVANCED_REWRITE.declare_rewrite_equivalence (
name => 'test_rewrite',
source_stmt => 'SELECT * FROM A1',
destination_stmt => 'SELECT * FROM A2',
validate => FALSE,
rewrite_mode => 'recursive');
END;
/
select * from A1;
ID NAME
---------- --------------------
2 Hola Mundo
1 Hello World
select * from A1 where id = 2;
ID NAME
---------- --------------------
2 Hola Mundo
explain plan for
select * from A1 where id = 2;
select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 1034670462
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 25 | 2 (0)| 00:00:01 |
| 1 | VIEW | A2 | 1 | 25 | 2 (0)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID | A1 | 1 | 25 | 2 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN DESCENDING| A1_IDX | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
---------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("ID"=2)
Note
-----
- dynamic sampling used for this statement (level=2)
- automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold
20 rows selected
As you can see
the engine is transparently applying the transformation and returning the filtered result
on top of that, the transformation on the filter is applied. The filter is correctly "pushed" into the source table, to extract the values from A1. It is not blindly extracting all values from A2 and then applying the filter, so the performance is preserved.

Resources