I have pl/sql anonymous block like below
declare
v_count pls_integer := 0;
begin
select count(1) from product_component_version
into v_count
where product like '%Enterprise%';
if v_count = 0 then
raise program_error;
end if;
exception
when program_error then
raise_application_error (-20001, 'This is valid for Oracle Enterprise Edition only!');
end;
When I try to execute the above,I am getting the below error
ORA-06550: line 5, column 5:
PL/SQL: ORA-00933: SQL command not properly ended
Which is nothing but for "into v_count" statement.
As per my understanding the syntax is wrong and when I changed that statemnt like below it is working fine.
select count(1) into v_count
from product_component_version
where product like '%Enterprise%';
I have tested this in "Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit".
But the original script is available in all our older versions of our product.
I would like to know the syntax in original script is supported in older oracle versions?
Or can you please let me know any information on this which can answer my confusion?
Thanks,
Vijay
With a test block:
declare
x dual.dummy%type;
begin
select dummy from dual into x;
end;
/
In Oracle 9iR2 (9.2.0.8 on Solaris), 10gR2 (10.2.0.5 on Solaris) and 11gR2 (11.2.0.3 on Linux) I get exactly the same error:
select dummy from dual into x;
*
ERROR at line 4:
ORA-06550: line 4, column 28:
PL/SQL: ORA-00933: SQL command not properly ended
ORA-06550: line 4, column 5:
PL/SQL: SQL Statement ignored
I don't believe it has ever been supported the way you had it, though I don't have an 8i or earlier database to test against.
You said 'the original script is available in all our older versions of our product', but would it actually ever have been run, and if so can you identify an exact version it didn't raise an error against?
At least not from 8i onwards:
http://www.oracle.com/pls/tahiti/tahiti.tabbed?section=49135
Even i don't thing so about select dummy from dual into x;
try this:
declare
v_count pls_integer := 0;
begin
select count(1) into v_count from product_component_version
where product like '%Enterprise%';
if v_count = 0 then
raise program_error;
end if;
exception
when program_error then
raise_application_error (-20001, 'This is valid for Oracle Enterprise Edition only!');
end;
Related
I am trying to run the sub-query based on version in Oracle. Since oracle released the new version 21c have to modify the query in that way.
I would like to check if the version is 19c then take the value from sys.aud$ else take the value AUDSYS.AUD$UNIFIED.
select version,
CASE
WHEN version <= '19.0.0.0.0' THEN (select * from sys.aud$)
ELSE
(select * from AUDSYS.AUD$UNIFIED)
END version_group
from v$Instance;
I am getting ORA-00913: too many values as the error.
If you are using PL/SQL then you can use conditional compilation. For example:
DECLARE
v_cur SYS_REFCURSOR;
BEGIN
OPEN v_cur FOR
select v.version, s.*
from v$Instance v
CROSS JOIN
$IF DBMS_DB_VERSION.VER_LE_19
$THEN
sys.aud$ s
$ELSE
AUDSYS.AUD$UNIFIED s
$END
;
END;
/
I'm giving a functionality which works on 12c and has JSON related operations.
but when database is 11g the JSON queries should be skipped. Need if condition for this but this should consider future approach as in it should be able to handle next oracle version.
E.g JSON supported in 12c and above but not below
with v$version I can compare string in if condition but it is static
current implementation as follows
SELECT substr(banner, 1, 19)banner
into x_version
FROM v$version
WHERE banner LIKE 'Oracle Database 12c%';
IF x_version = 'Oracle Database 12c' THEN ...
You could use conditional compilation, based on dbms_db_version values:
declare
$if not dbms_db_version.ver_le_11_2 $then
l_var number;
$end
begin
$if dbms_db_version.ver_le_11_2 $then
null;
$else
select json_value('{x:42}', '$.x') into l_var from dual;
dbms_output.put_line('12c+: ' || l_var);
$end
end;
/
On 11gR2 this just gets:
PL/SQL procedure successfully completed.
On 12c it gets:
12c+: 42
PL/SQL procedure successfully completed.
Wrap any variable declarations that are only relevant to 12c+ operations, and any code that you only want to call in 12c and above, in conditions.
Of course, this will only work on version 11gR2 or above; if you need to be able to run (without doing anything) on 11gR1 then change the check to ver_le_11. Even that won't be recognised if you try to run on a 10g or earlier database though.
If you need to handle other earlier versions, you can check the version number directly (as #Wernfried showed):
declare
$if dbms_db_version.version >= 12 $then
l_var number;
$end
begin
$if dbms_db_version.version >= 12 $then
select json_value('{x:42}', '$.x') into l_var from dual;
dbms_output.put_line('12c+: ' || l_var);
$else
null;
$end
end;
/
The $else null; part is only needed because I have nothing else in my block - I would get PLS-00103: Encountered the symbol "END" ... without it (in 11g or earlier). If there is other unconditional code then that isn't necessary, though it may still be clearer to include it.
What about this?
DECLARE
ver number;
BEGIN
DBMS_OUTPUT.PUT_LINE ( 'DBMS_DB_VERSION.VERSION = ' || DBMS_DB_VERSION.VERSION );
DBMS_OUTPUT.PUT_LINE ( 'DBMS_DB_VERSION.RELEASE = ' || DBMS_DB_VERSION.RELEASE );
ver := (10*DBMS_DB_VERSION.VERSION + DBMS_DB_VERSION.RELEASE) / 10;
DBMS_OUTPUT.PUT_LINE ( 'ver = ' || ver );
end;
DBMS_DB_VERSION.VERSION = 12
DBMS_DB_VERSION.RELEASE = 1
ver = 12.1
Or you may use
SELECT VALUE
FROM NLS_DATABASE_PARAMETERS
WHERE PARAMETER = 'NLS_RDBMS_VERSION';
I have the a sql file containing the following:
Note that the CDB column in v$database only exists when version (not Oracle but of some other unrelated product) is greater than 11.
It runs fine when I execute it on DB host using sqlplus
sqlplus / as sysdba #abc.sql 1000 60 10
However, when I connect to this DB host remotely using connection string, it complains about "Invalid identifier" if CDB column does not exist (no matter what version value I specify)
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage
Management, Oracle Label Security,
OLAP, Data Mining, Oracle Database Vault and Real Application Testing options
.
old 2: num_ret_period NUMBER(9) :=
new 2: num_ret_period NUMBER(9) := 43200;
old 3: num_interval NUMBER(9) :=
new 3: num_interval NUMBER(9) := 60;
old 5: lcm_version NUMBER(4) :=
new 5: lcm_version NUMBER(4) := 1;
SELECT CDB INTO isCDB from v$database;
*
ERROR at line 10:
ORA-06550: line 10, column 12:
PL/SQL: ORA-00904: "CDB": invalid identifier
ORA-06550: line 10, column 5:
PL/SQL: SQL Statement ignored
Any ideas why?
DECLARE
num_ret_period NUMBER(9) := &1;
num_interval NUMBER(9) := &2;
isCDB VARCHAR2(10);
version NUMBER(4) := &3;
BEGIN
IF version > 11 THEN
SELECT CDB INTO isCDB from v$database;
IF (isCDB = 'YES') THEN
EXECUTE IMMEDIATE 'ALTER session SET CONTAINER = CDB$ROOT';
dbms_output.put_line('CDB is set to YES');
ELSE
dbms_output.put_line('CDB is set to NO');
END IF;
END IF;
callSomeProcedure();
commit;
EXCEPTION
when others then
dbms_output.put_line('There is an exception in abc.sql' || SQLCODE || ' ' || SQLERRM);
ROLLBACK;
raise_application_error(-20001, 'There is an exception in abc.sql' || SQLCODE || ' ' || SQLERRM);
END;
/
Even if you do not intend to execute the code guarded by if version > 11 it still needs to be parsed. At this point the fact that CDB does not exist (version 11) is revealed.
To avoid this, use conditional compilation:
$IF DBMS_DB_VERSION.VER_LE_11 $THEN
-- version 11 code
NULL;
$ELSE
-- version 12 and later code
NULL;
$END
The conditional compilation directives act similar to a preprocessor.
See https://oracle-base.com/articles/10g/conditional-compilation-10gr2
I am getting the error at line 7 (see the code below) which is specified by 10g as :
"Statement ignored"
Can anyone tell me what I'm doing wrong?
create or replace trigger demo1_bifer
BEFORE INSERT ON demo1
FOR EACH ROW
declare
lock_id number;
resource_busy exception;
pragma EXCEPTION_INIT(resource_busy,-54);
begin
lock_id := dbms_utility.get_hash_value(to_char(:new.x),0,1024);
if (dbms_lock.request( id => lock_id,lockmode => dbms_lock.x_mode, timeout => 0, release_on_commmit => TRUE) not in (0,4))
then raise resource_busy;
end if;
end;
/
You have mistyped commit in the parameter name release_on_commmit. Delete one of the three ms.
On my system (Oracle 11g XE) I also got an error PLS-00201: identifier 'DBMS_LOCK' must be declared. To fix this I needed to grant EXECUTE on DBMS_LOCK to the user I was creating the trigger as.
I'm new to pl/SQL. The error I'm getting is :
ORA-06550: line 3, column 2: PL/SQL: ORA-00933: SQL command not properly ended
ORA-06550: line 2, column 1: PL/SQL: SQL Statement ignored
So far I have tried adding parentheses, but no luck. I know its a syntax error, but I'm not sure where my mistake is. I tested each line , line by line and I believe there is a problem with my if statement. Does anyone know how I can fix the error for the following code?
SELECT CITRIX from SWLR_ASSET where swlr_key = :p26_swlr_id
if CITRIX=1 then --If Citrix installation is required
UPDATE SOFTWARE_REPORT_DASHBOARD
SET TOTAL_CITRIX_LICENSES=TOTAL_CITRIX_LICENSES+1
WHERE SOFTWARE_NAME=select (Software_name||' ,'||software_version) from swlr_software where software_id = (select software from swlrequest where swlr_id = :p26_swlr_id)
else --If manual installation is required
UPDATE SOFTWARE_REPORT_DASHBOARD
SET TOTAL_PHYSICAL_LICENSES=TOTAL_PHYSICAL_LICENSES+1
WHERE SOFTWARE_NAME= select (Software_name||' ,'||software_version) from swlr_software where software_id = (select software from swlrequest where swlr_id = :p26_swlr_id)
end if;
when you want to a write in plsql a block statement you have to include begin and end; and you have to decalre your variables
declare p26_swlr_id number(specify a number);
v_name varchar2(500);
v_name1 varchar2(500);
begin
p26_swlr_id :=33;( or if its from a table select swrl_id into p26_swlr_id from table where something);
-- this to give you the values for your conditions , its not tested though, and from your condition it should return one record.
select (Software_name||' ,'||software_version) into V_name from swlr_software where software_id = (select software from swlrequest where swlr_id = p26_swlr_id)
select (Software_name||' ,'||software_version into V_name1 from swlr_software where software_id = (select software from swlrequest where swlr_id = :p26_swlr_id)
-- you have to put `;` when you end select
SELECT CITRIX from SWLR_ASSET where swlr_key = p26_swlr_id;
if CITRIX=1 then --If Citrix installation is required
UPDATE SOFTWARE_REPORT_DASHBOARD
SET TOTAL_CITRIX_LICENSES=TOTAL_CITRIX_LICENSES+1
WHERE SOFTWARE_NAME=V_name;
else --If manual installation is required
UPDATE SOFTWARE_REPORT_DASHBOARD
SET TOTAL_PHYSICAL_LICENSES=TOTAL_PHYSICAL_LICENSES+1
WHERE SOFTWARE_NAME= V_name2;
end if;
end;
/
Try to declare a variable and then use the select into statement.
SELECT CITRIX into V_CITRIX from SWLR_ASSET where swlr_key...
Then where you compare, use the variable.
if V_CITRIX=1 then
...
And why aren't you using declare/begin/end? From where are you getting the parameters?