PL/SQL Block returns ORA-06553: PLS-114: identifier 'MyMSAccessFieldIsOver30CharsLong' too long when using a Remote NON-Oracle Database - oracle

I have a database link to a MS Access database in an Oracle database using Oracle's Heterogeneous Services. Some of the Access table column names are longer than the Oracle allowed 30 characters. As a result, my PL/SQL code is returning an error:
declare
my_record myaccesstable#MSAccessODBC64%rowtype;
begin
null;
--dbms_output.put_line(my_record."flight_pattern_combination_string");
end;
/
declare
*
ERROR at line 1:
ORA-04052: error occurred when looking up remote object BASE.MSNS_MISSIONS#AMGBASETABLES64
ORA-00600: internal error code, arguments: [kglhfr-bad-free], [], [], [], [], [], [], [], [], [], [], []
ORA-06553: PLS-114: identifier 'flight_pattern_combination_str' too long
Is there a way to trim or truncate the column names when using the %rowtype syntax? I'm not allowed to modify the Access database. I can use a record data type declaration, but this would involve copying all of the column data types into a pl/sql block or package. I tried to use the following:
create table test as select * from myaccesstable#MSAccessODBC64
*
ERROR at line 1:
ORA-00997: illegal use of LONG datatype
Is there a way to trim or truncate the column names when using the %rowtype syntax in a PL/SQL Block?

I am not sure what exactly your requirement is, but Did you try creating a View based on the table
create or replace view vw (col1) as select flight_pattern_combination_str from myaccesstable#MSAccessODBC64
and then use that view in your procedure.

Related

ORACLE: Cannot bind parameter to create table AS subquery

CREATE PRIVATE TEMPORARY TABLE ORA$PTT_collection_ids
ON COMMIT PRESERVE DEFINITION AS (
SELECT
DISTINCT cms3_dc_language.collection_id AS "collection_id"
FROM
cms3_dc_language
WHERE
cms3_dc_language.language = :language)
$sth->bindParam(":language", $language);
Gives an error when trying to bind :language...
OCIBindByName: ORA-01036: illegal variable name/number
The bind works if the bound parameter is not part of the create table AS subquery e.g.
SELECT
DISTINCT cms3_dc_language.collection_id AS "collection_id"
FROM
cms3_dc_language
WHERE
cms3_dc_language.language = :language
$sth->bindParam(":language", $language);
If you do the same thing using execute immediate you can see the real issue:
ORA-01027: bind variables not allowed for data definition operations
Although a bind variable is allowed as part of a query (obviously), here the query is a secondary factor, and it's the DDL that is the problem. You'd get the same error with a normal, non-temporary, table or a view, for instance.

Creating a Snowflake View with a Sequence

Is it possible to use a Sequence inside a View?? I am using the following query:
CREATE VIEW < VIEW_NAME > (ID, VALUE1, VALUE2,...) AS
SELECT
SEQ1.NEXTVAL,
VAL1,
VAL2,
...
FROM
< TABLE >
But it is giving me the following error:
invalid identifier 'SEQ1.NEXTVAL'
The query works when not creating the view:
use the full qualified name for the SEQ object, because if I am in a different DB/Schema, that is the scope used to look for SEQ
basically everything in a view should be fully qualified, tables, views, functions, sequences.
CREATE DATABASE test;
create SCHEMA test.test;
use SCHEMA test.test;
create SEQUENCE seq1;
create view test_v as SELECT seq1.nextval;
select * from test.test.test_v;
gives:
NEXTVAL
2
create SCHEMA test.not_test;
use SCHEMA test.not_test;
select * from test.test.test_v;
and now you get:
SQL compilation error: error line 1 at position 29 invalid identifier 'SEQ1.NEXTVAL'
Here SEQ1 is not defined, that is the reason why you see the error. Documentation for Sequences is here:
https://docs.snowflake.com/en/sql-reference/sql/create-sequence.html
Is the Sequence existing? Looks like you accidentally missed to create it.

Create Type based on an exiting Table

As the title said : I want to create a type in oracle based on an existing Table.
I did as follow :
create or replace type MY_NEW_TYPE as object( one_row EXISTING_TABLE%rowtype);
The Aim is to be able to use this into a function which will return a table containing sample row of the table EXISTING_TABLE :
create or replace function OUTPUT_FCT() return MY_NEW_TYPE AS
...
If you only need to create a function that returns a row from your table, you could try something like the following, without creating types.
setup:
create table EXISTING_TABLE( a number, b varchar2(100));
insert into EXISTING_TABLE values (1, 'one');
function:
create or replace function OUTPUT_FCT return EXISTING_TABLE%rowtype AS
retVal EXISTING_TABLE%rowType;
begin
select *
into retVal
from EXISTING_TABLE
where rownum = 1;
--
return retVal;
end;
function call
SQL> begin
2 dbms_output.put_line(OUTPUT_FCT().a);
3 dbms_output.put_line(OUTPUT_FCT().b);
4 end;
5 /
1
one
However, I would not recommend such an approach, because things like select * can be really dangerous; I would much prefer defining a type with the fields I need, and then explicitly query my table for the needed columns.
No, you can't do that, you'll get a compilation error:
create or replace type my_new_type as object(one_row t42%rowtype);
/
Type MY_NEW_TYPE compiled
Errors: check compiler log
show errors
Errors for TYPE STACKOVERFLOW.MY_NEW_TYPE:
LINE/COL ERROR
-------- -----------------------------------------------------------------------
0/0 PL/SQL: Compilation unit analysis terminated
1/36 PLS-00329: schema-level type has illegal reference to MYSCHEMA.T42
You will need to specify each field in the object type, and you will have to specify the data types manually too - you can't use table.column%type either.
You could create the type dynamically based on column and data type information from the data dictionary, but as this will (hopefully) be a one-off task and not something you'd do at runtime, that doesn't really seem worth it.
You can create a PL/SQL table type based on your table's rowtype, but you would only be able to call a function returning that from PL/SQL, not from plain SQL - so you couldn't use it in a table collection expression for example. If you were only returning a single sample row you could return a record rather than a table, but the same applies. You can also have a function that returns a ref cursor which could match the table's structure, but you wouldn't be able to treat that as a table either.
Read more about object type creation in the documentation. Specifically the attribute and datatype sections.

No more data to read from socket (Oracle SQL Developer)

I have created one trigger that calls one procedure, using oracle sql developer. Here is the code for trigger:
CREATE OR REPLACE TRIGGER noteTrigger
BEFORE
INSERT OR
UPDATE OF valoare OR
DELETE
ON note
BEGIN
CASE
WHEN INSERTING THEN
DBMS_OUTPUT.PUT_LINE('Inserting');
updateBursa();
WHEN UPDATING('valoare') THEN
DBMS_OUTPUT.PUT_LINE('Updating valoare');
updateBursa();
WHEN DELETING THEN
DBMS_OUTPUT.PUT_LINE('Deleting');
updateBursa();
END CASE;
END;
/
Now, the procedure is written here:
CREATE OR REPLACE PROCEDURE updateBursa IS
v_countBursieri NUMBER := 0;
BEGIN
UPDATE STUDENTI SET bursa = null;
FOR v_i IN (SELECT nr_matricol from studenti natural join note group by nr_matricol having avg(valoare) =
(select max(avg(valoare)) from studenti natural join note group by nr_matricol)) LOOP
v_countBursieri := v_countBursieri + 1;
END LOOP;
FOR v_i IN (SELECT nr_matricol from studenti natural join note group by nr_matricol having avg(valoare) =
(select max(avg(valoare)) from studenti natural join note group by nr_matricol)) LOOP
UPDATE STUDENTI SET bursa = 1000/v_countBursieri where nr_matricol = v_i.nr_matricol;
END LOOP;
END;
/
And when I try to modify note table by this:
INSERT INTO note VALUES ('111', '25', 5, TO_DATE('20/06/2015', 'dd/mm/yyyy'));
I get error:
Error report -
ORA-00603: ORACLE server session terminated by fatal error
ORA-00600: internal error code, arguments: [kqlidchg0], [], [], [], [], [], [], [], [], [], [], []
ORA-00604: error occurred at recursive SQL level 1
ORA-00001: unique constraint (SYS.I_PLSCOPE_SIG_IDENTIFIER$) violated
00603. 00000 - "ORACLE server session terminated by fatal error"
*Cause: An Oracle server session was in an unrecoverable state.
*Action: Log in to Oracle again so a new server session will be created
automatically. Examine the session trace file for more
information.
Error report -
SQL Error: No more data to read from socket
This is Ora-600 you should deeply explore reasons why is raised in your case, maybe you should open SR.
also, in the code you are referencing the table "note" on which you are creating a trigger, which could lead to mutating table, so consider the option of changing your code logic.
In my understanding, you need statement level trigger, not row level trigger?
ORACLE server session terminated by fatal error
Try this, had the same problem on the same "topic" let's say :) And setting things as shown previously just solved my problem. Good luck!

ORA-06550 using a nested table type

I'm trying to create some output based on select items from APEX.
The case is as follows:
In APEX you select certain items.
APEX makes a nested table of those primary keys and call the function to create the output.
The function generates the output and returns it.
I already found out that I can't use locally defined nested tables in the where clause, but I am now stuck on the following:
My stored type:
CREATE OR REPLACE EDITIONABLE TYPE "T_NUMBERS" as table of NUMBER(10,0)
The part of the function that gives the ORA-06550 error:
DECLARE
c_asked T_NUMBERS;
BEGIN
c_asked := T_NUMBERS(21);
This is just a simple example of what is going wrong.
The error itself:
ORA-06550: line 9, column 23:
PL/SQL: ORA-00932: inconsistent datatypes: expected NUMBER got <schema_name>.T_NUMBERS

Resources