PL/SQL: SELECT INTO raises ORA-00947 - sql

I'm using Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
I've created an object type:
SQL> create or replace type TestObject as Object (
2 id INTEGER,
3 name VARCHAR2(10)
4 );
5 /
Then I create a table containint objets of that type:
SQL> CREATE TABLE TestTable of TestTable;
and I populate the table with some data:
SQL> INSERT INTO TestTable VALUES (10, 'John');
Now, if I want to perform a SELECT in PL/SQL:
SQL> declare
2 aTest TestObject;
3 begin
4 select * into aTest from TestTable;
5 end;
6 /
I get the error ORA-00947 (not enough values):
select * into aTest from TestTable;
*
ERROR en línea 4:
ORA-06550: línea 4, columna 21:
PL/SQL: ORA-00947: no hay suficientes valores
ORA-06550: línea 4, columna 1:
PL/SQL: SQL Statement ignored
But the TestTable contains objects of type TestObject and the variable aTest is also of type TestObject ... ¿Where is the mismatch in the number of values?

For me this worked:
declare
ta TestObject;
begin
select TestObject(t.id, t.name) into ta from TestTable t;
end;
/

Try This..
select TestObject(id,name) from TestTable
/

Related

Oracle SQL - How to define a date bind variable based on a select statement

Using Oracle SQL, I have several SQL Queries with manual bind variables that are used to create a table as follows:
What I would like to do is to change the define anfang to (select c_year_beginning from master_date_automation).
I have tried several combinations of bind variables but could not make it work (edited with DEL comments):
begin
execute immediate 'DROP TABLE A_TEST_TABLE'
end;
/
begin
execute immediate 'create table A_TEST_TABLE (
user varchar2(100),
product varchar2(100),
datum date)';
end;
/
BEGIN
DECLARE
v_c_year_ytd DATE;
BEGIN
SELECT c_year_ytd Into v_c_year_ytd FROM master_date_automation;
BEGIN
SELECT usr.datum || ','
|| usr.user || ','
|| usr.product
INTO A_TEST_TABLE
FROM users_table usr
WHERE usr.datum = v_c_year_ytd
AND kto.kontonummer = '00510199065';
END;
END;
END;
ERROR message (edited after Del comment):
Error report -
ORA-06550: line 12, column 6:
PLS-00403: expression 'A_TEST_TABLE' cannot be used as an INTO-target of a SELECT/FETCH statement
ORA-06550: line 12, column 21:
PL/SQL: ORA-00904: : invalid identifier
ORA-06550: line 9, column 1:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Would be really thankful if someone could help me out.
Thousand thanks in advance!
So, to sum up my comments from above, you don't need PL/SQL to do this. You could do all of your script with straight SQL:
CREATE TABLE A_TEST_TABLE
(
user varchar2(100),
product varchar2(100),
datum date
);
INSERT INTO a_test_table
SELECT usr.user,
usr.product,
usr.datum
FROM users_table
WHERE usr.datum = (SELECT c_year_ytd FROM master_date_automation)
AND usr.user= '123456789'
Drop the table if you need to first.
You don't need to use dynamic SQL inside a PL/SQL block to create the tables; you can do it using SQL statements:
DROP TABLE A_TEST_TABLE;
CREATE TABLE A_TEST_TABLE (
user_name varchar2(100),
product varchar2(100),
datum date
);
Note: USER is a reserved word and you CANNOT use it as an unquoted identifier; you will need to find another identifier such as user_name or you will have to use a quoted identifer and refer to it as "USER" everywhere it is used (however, that is bad practice).
Then if you want to use PL/SQL you can use:
DECLARE
v_c_year_ytd DATE;
BEGIN
SELECT c_year_ytd
Into v_c_year_ytd
FROM master_date_automation;
INSERT INTO a_test_table (datum, user_name, product)
SELECT datum,
user_name
product
FROM users_table
WHERE datum = v_c_year_ytd
AND kontonummer = '00510199065';
END;
/
But it would be much simpler to just use one SQL statement:
INSERT INTO a_test_table (datum, user_name, product)
SELECT datum,
user_name
product
FROM users_table
WHERE datum = (SELECT c_year_ytd FROM master_date_automation)
AND kontonummer = '00510199065';

Issue with Oracle SQL

Can anyone tell me why I'm getting error below:
"ORA-00904: "MESSAGE_BODY": invalid identifier"
When I run below query against an Oracle database?
SELECT COMMERCIAL_ID, MIN(dbms_lob.substr(MESSAGE_BODY, 3999, 1)) AS MESSAGE_BODY
FROM DWH_F_MP_MESSAGE_VW
GROUP BY COMMERCIAL_ID;
MESSAGE_BODY field is a CLOB
It seems that DWH_F_MP_MESSAGE_VW doesn't contain a column named MESSAGE_BODY.
Here's a demonstration:
SQL> create table dwh_f_mp_message_vw (commercial_id number, message_body clob);
Table created.
SQL> insert into dwh_f_mp_message_vw values (1, 'Littlefoot');
1 row created.
SQL> select commercial_id, min(dbms_lob.substr(message_body, 3999, 1))
2 from dwh_f_mp_message_vw
3 group by commercial_id;
COMMERCIAL_ID
-------------
MIN(DBMS_LOB.SUBSTR(MESSAGE_BODY,3999,1))
--------------------------------------------------------------------------------
1
Littlefoot
SQL> select commercial_id, min(dbms_lob.substr(message_bodyyyyyy, 3999, 1))
2 from dwh_f_mp_message_vw
3 group by commercial_id;
select commercial_id, min(dbms_lob.substr(message_bodyyyyyy, 3999, 1))
*
ERROR at line 1:
ORA-00904: "MESSAGE_BODYYYYYY": invalid identifier
SQL>
I suggest you run this:
SQL> desc dwh_f_mp_message_vw
Name Null? Type
----------------------------------------- -------- ----------------
COMMERCIAL_ID NUMBER
MESSAGE_BODY CLOB
and post the result back here (unless you figure it out; in that case, please, explain what went wrong). A possible culprit is a column created under double quotes, e.g.
SQL> drop table dwh_f_mp_message_vw;
Table dropped.
SQL> create table dwh_f_mp_message_vw (commercial_id number, "message_body" clob);
Table created.
SQL> insert into dwh_f_mp_message_vw (commercial_id, message_body) values (1, 'Littlefoot');
insert into dwh_f_mp_message_vw (commercial_id, message_body) values (1, 'Littlefoot')
*
ERROR at line 1:
ORA-00904: "MESSAGE_BODY": invalid identifier
SQL> insert into dwh_f_mp_message_vw (commercial_id, "message_body") values (1, 'Littlefoot');
1 row created.
SQL> desc dwh_f_mp_message_vw
Name Null? Type
----------------------------------------- -------- -------------------
COMMERCIAL_ID NUMBER
message_body CLOB
SQL>
If that's so, get rid of double quotes.

Select Object Table Into Variable

I've got a problem with trying to select something from a object table into my own local variable. Here's some basic code.
create type my_obj as object
(
my_number number
)
/
create table my_table of my_obj;
/
insert into my_table values (my_obj(123))
/
declare
my_holder my_obj;
begin
select * into my_holder from my_table where rownum = 1;
dbms_output.put_line(my_holder.my_number);
end;
The error I'm getting out of it is
Error starting at line : 86 in command -
declare
my_holder my_obj;
begin
select * into my_holder from my_table where rownum = 1;
end;
Error report -
ORA-06550: line 4, column 10:
PL/SQL: ORA-00932: inconsistent datatypes: expected UDT got NUMBER
ORA-06550: line 4, column 3:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Any clues on why this might be failing?
The select returns the variables from the object not the object itself so if you wanted to get it to work the way you have it you would need to declare that you want the object returned as below.
select my_obj(my_number) into my_holder from my_table where rownum = 1;
Hope this helps

Insert data from table to another table using PL/SQL

I have a table which called Logiciel :
Name Null? Type
---------- -------- -------------
NLOG NOT NULL VARCHAR2(5)
NOMLOG NOT NULL VARCHAR2(20)
DATEACH DATE
VERSION VARCHAR2(7)
TYPELOG VARCHAR2(9)
PRIX NUMBER(6,2)
Using PL/SQL I want to add an entry which has the same data as the entry with NLOG = 'log3', and the value PRIX as the average of PRIX : AVG(PRIX) of all entries.
This is the script I wrote:
DECLARE
unLog LOGICIEL%ROWTYPE;
moy LOGICIEL.PRIX%TYPE;
BEGIN
SELECT AVG(PRIX) INTO moy FROM LOGICIEL;
SELECT * INTO unLog FROM LOGICIEL WHERE NLOG='log5';
unLog.PRIX := moy;
unLog.NLOG := 'logS';
INSERT INTO LOGICIEL SELECT * FROM unLog;
END;
/
The problem is when I execute this script I get this error :
ERROR at line 9:
ORA-06550: line 9, column 37:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 9, column 2:
PL/SQL: SQL Statement ignored
How can I solve this problem ?
Just use insert . . . select:
INSERT INTO LOGICIEL(NLOG, NOMLOG, DATEACH, VERSION, TYPELOG, PRIX)
SELECT NLOG, NOMLOG, DATEACH, VERSION, TYPELOG,
(SELECT AVG(PRIX) FROM LOGICIEL) as PRIX
FROM LOGICIEL
WHERE NLOG = 'log3';
EDIT:
Is this what you mean?
INSERT INTO LOGICIEL(NLOG, NOMLOG, DATEACH, VERSION, TYPELOG, PRIX)
SELECT unlog.NLOG, unlog.NOMLOG, unlog.DATEACH, unlog.VERSION, unlog.TYPELOG, unlog.PRIX
FROM dual;

Insert row to table B before updating it in table A

I have a table called applications and a table called application_history. I want to keep a history of applications and had the idea of using a trigger whenever a row gets updated in the applications table to copy that row to application_history before it is actually updated.
At the moment, I've written this code out from another SO post:
create or replace
trigger APPLICATION_UPDATE_TRG
BEFORE UPDATE ON TBL_APPLICATIONS
FOR EACH ROW
DECLARE
CURSOR curAppHistory IS
SELECT record_number, job_id, submitted_date, status_id, id
FROM tbl_application
WHERE id = :old.id;
vRowAppHistory curAppHistory%ROWTYPE;
BEGIN
OPEN curAppHistory;
FETCH curAppHistory INTO vRowAppHistory;
CLOSE curAppHistory;
INSERT INTO tbl_application_history
(record_number, job_id, submitted_date, status_id, application_id)
VALUES (vRowAppHistory.record_number, vRowAppHistory.job_id, vRowAppHistory.submitted_date,
vRowAppHistory.status_id, vRowAppHistory.id);
END;
However, it's not properly compiling. SQL Developer throws out 3 errors about commands not properly ended and statements being ignored.
What's the proper way to do this?
Edit: The errors:
Error(2,10): PLS-00341: declaration of cursor 'CURAPPHISTORY' is incomplete or malformed
Error(3,5): PL/SQL: SQL Statement ignored
Error(4,12): PL/SQL: ORA-00942: table or view does not exist
Error(6,18): PL/SQL: Item ignored
Error(9,3): PL/SQL: SQL Statement ignored
Error(9,28): PLS-00320: the declaration of the type of this expression is incomplete or malformed
Error(11,3): PL/SQL: SQL Statement ignored
Error(14,29): PLS-00320: the declaration of the type of this expression is incomplete or malformed
Error(14,44): PL/SQL: ORA-00984: column not allowed here
Error(4,12): PL/SQL: ORA-00942: table or view does not exist
A typo? You specified two different tables here.
BEFORE UPDATE ON TBL_APPLICATIONS
FROM tbl_application
Anyway, you'll get ORA-04091 with this trigger. Similar test case:
SYSTEM#dwal> create table t (key number primary key, value varchar2(10));
Table created.
SYSTEM#dwal> insert into t values (1, 'abcdef');
1 row created.
SYSTEM#dwal> insert into t values (2, 'ghijkl');
1 row created.
SYSTEM#dwal> commit;
Commit complete
SYSTEM#dwal> ed
Wrote file S:\\tools\buffer.sql
1 create or replace trigger tt
2 before update on t for each row
3 declare
4 cursor c is
5 select key, value
6 from t
7 where key = :old.key;
8 v c%rowtype;
9 begin
10 open c;
11 fetch c into v;
12 close c;
13 dbms_output.put_line(v.value);
14* end;
09:58:51 SYSTEM#dwal> /
Trigger created.
SYSTEM#dwal> update t set value = '123';
update t set value = '123'
*
ERROR at line 1:
ORA-04091: table SYSTEM.T is mutating, trigger/function may not see it
ORA-06512: at "SYSTEM.TT", line 3
ORA-06512: at "SYSTEM.TT", line 8
ORA-04088: error during execution of trigger 'SYSTEM.TT'
You should probably do it like this:
INSERT INTO tbl_application_history
(record_number, job_id, submitted_date, status_id, application_id)
VALUES
(:old.record_number, :old.job_id, :old.submitted_date, :old.status_id, :old.id);
The whole trigger would be a single insert statement in this case:
SYSTEM#dwal> create table t_log (key number, value varchar2(10));
Table created.
SYSTEM#dwal> ed
Wrote file S:\\tools\buffer.sql
1 create or replace trigger tt
2 before update on t for each row
3 begin
4 insert into t_log values (:old.key, :old.value);
5* end;
SYSTEM#dwal> /
Trigger created.
SYSTEM#dwal> update t set value = '123';
2 rows updated.
SYSTEM#dwal> commit;
Commit complete.
SYSTEM#dwal> select * from t_log;
KEY VALUE
---------- ----------
1 abcdef
2 ghijkl
SYSTEM#dwal> select * from t;
KEY VALUE
---------- ----------
1 123
2 123