I want to create a procedure that deletes the employee with the greatest salary. I have this code:
create or replace procedure DelMostExpensive
as
begin
delete from hr.Employees where
hr.Employees.EmpName=
(select EmpName from hr.Employees where
salary = (select max(salary) from hr.Employees))
and hr.Employees.birthDate=
(select birthDate from hr.Employees where
salary = (select max(salary) from hr.Employees));
end;
But I get these errors:
Error(4,1): PL/SQL: SQL statement ignored.
Error(4,16): PL/SQL: Ora-00942 table or view does not exist.
How to make it work?
Look at line 4:
delete from hr.Almalmazott2 where
Do you know what table you're trying to delete from? This looks like a table column.
Related
I looking for get metadata on a TFDQuery (FireDAC).
I have this query:
SELECT *
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.Code = t2.code
I would like to know the column information (table name, the real column name in the table, ....)
I find this post : How to get the table name from a field in a join query with MSSQL? (mysql_field_table equivalent) but I have not the same structure on FireDac.
As RBA already mentioned you have to enable ExtendedMetaData in the connection first. When done you can get the field column description via query.GetFieldColumn(field) and access the table and column name with its ActualOriginTabName and ActualOriginColName properties.
column := query.GetFieldColumn(field);
orgTableName := column.ActualOriginTabName;
orgColumnName := column.ActualOriginColName;
I am trying to copy over one row from my archive table to my original table.
Without my WHERE clause, the whole table of table2 gets copied to table1.
I don't want this of course. So based on the gridview's ID value listed, the table will copy over only the row whose ID is the same.
When I debug the lines I get the correct ID listed for DisplaySup.Rows(0).Cells(2).Text.
(
val_ID table2.V_ID%type
)
is
begin
execute immediate 'insert into table1 (select * from table2 where V_ID = val_ID)';
end;
Yet I get the error
ORA-00904: "VAL_ID": invalid identifier
Table2 and Table1 have identical columns; so they both have column titled V_ID. I am unsure why Val_ID is flagging an error.
VB.net line of coding:
SupArchive.Parameters.Add("val_ID", OleDbType.VarChar).Value = DisplaySup.Rows(0).Cells(2).Text
So I tried to reference: EXECUTE IMMEDIATE with USING clause giving errors
Like so to fix WHERE:
(
val_ID table2.V_ID%type
)
is
begin
execute immediate 'insert into table1 (select * from table2 where V_ID = '||val_ID||')';
end;
but I get error:
ORA-00904: "val_ID": invalid identifier
Any suggestions on how to fix my stored procedure?
UPDATE:
Tried to do the suggested:
(
val_ID table2.V_ID%type
)
AS
BEGIN
execute immediate 'insert into table1 (col1, col2, col3...)(select col1, col2, col3... from table2 where V_ID = :val_ID)' using val_ID;
end;
but get error:
ORA-00904: "col72": invalid identifier
for col72 after Select statement
EXAMPLE OF MY TABLES (both are identical) purpose of table2 is when a row is deleted in table1, table2 can re-create the user that was deleted
Table1
ID CompanyName FirstName LastName ....(72 cols)
Table2
ID CompanyName FirstName LastName... (72 cols)
You would do best to use a bind variable in your insert statement. Also, you need to list the columns you're inserting into as well as those you're inserting, to avoid the "too many values" error.
Eg:
declare
val_ID table2.V_ID%type := 1;
begin
execute immediate 'insert into table1 (col1, col2, ...) (select col1, col2, ... from table2 where V_ID = :val_ID)' using val_id;
end;
/
Although in this instance there is absolutely no need to use dynamic sql at all, so you could just do:
declare
val_id table2.v_id%type := 1;
begin
insert into table1 (col1, col2, ...)
select col1, col2, ...
from table2
where v_id = val_id;
end;
/
Don't forget to commit after you've run the procedure!
I have a stored procedure for Oracle 10g that needs to create a new row in the table and not create duplicates.
The table allows duplicates, so long as all columns are not the same. This is because the last two columns can differ in values.
With that being said, when I try to store my procedure I get the following flags:
Line # = 10 Column # = 1 Error Text = PL/SQL: SQL Statement ignored
Line # = 13 Column # = 3 Error Text = PL/SQL: ORA-00933: SQL command not properly ended
The procedure looks fine [given I haven't added a WHERE clause for an insert before like this].
So either my format isn't what it should be or my logic is off.
Whatever the case may be, I have tried finding examples online and on stackoverflow and have fallen short.
Any suggestions on how I should tweak this?
(val_ID tablename.column1%type,
val_cat tablename.column2%type,
val_sub tablename.column3%type
)
AS
BEGIN
INSERT INTO tablename (column1, column2, column3)
VALUES (val_ID, val_cat, val_sub)
WHERE ((column1 != val_ID) and (column2 != val_cat) and (column3 != val_sub));
COMMIT;
END;
I have even removed the "(" in WHERE clause and nothing changed.
UPDATE:
tried the suggestion and all errors are gone [however the record didn't create]
(val_ID tablename.column1%type,
val_cat tablename.column2%type,
val_sub tablename.column3%type
)
AS
BEGIN
INSERT INTO tablename (column1, column2, column3)
SELECT val_ID, val_cat, val_sub
FROM dual
MINUS
SELECT val_ID, val_cat, val_sub
FROM tablename;
The insert statement doesn't have a where clause. You could emulate it, though, by using an insert-select statement:
INSERT INTO tablename (column1, column2, column3)
SELECT val_ID, val_cat, val_sub
FROM dual
MINUS
SELECT column1, column2, column3
FROM tablename;
#Mureinik 's example did negate all my errors; however, when tested it didn't create the new row.
So my current work around will be a query in VB.net checking if the value exists and then implementing a simple insert stored procedure:
//Make select statement and look at table for whether more than 0 rows shows up. If 0 rows, then execute stored procedure
If DsAds1.Tables(0).Rows.Count = 0 Then
...do stored procedure
End If
Stored Procedure
(val_ID tablename.column1%type,
val_cat tablename.column2%type,
val_sub tablename.column3%type
)
AS
BEGIN
INSERT INTO tablename (column1, column2, column3)
VALUES( val_ID, val_cat, val_sub);
COMMIT;
END;
I am writing a stored procedure in SQL Server 2012 and facing problem while reading the number of rows that the stored procedure will return after matching all the conditions and join criteria.
My stored procedure is:
SELECT DISTINCT
COUNT(crs.CourseId) OVER() AS Recordcounts,
crs.CourseId,
crs.CourseName,
crs.CourseDescription,
(SELECT CourseGroupName FROM CourseGroup cgrp
WHERE cgrp.CourseGroupId = crs.CourseGroupId) AS Category
FROM
Courses crs
INNER JOIN
CourseRequests creq ON crs.CourseId = creq.CourseId
WHERE
crs.Coursename <> ''''
It is returning 16 as "Recordcounts" for one of condition, but in actual, the result is 3 rows only.
Can anybody help me with this?
Thanks
Below screenshot will give more clear idea about problem for one of condition:
Try this:
;with cte as(
SELECT distinct
crs.CourseId,
crs.CourseName,
crs.CourseDescription,
(SELECT CourseGroupName FROM CourseGroup cgrp
WHERE cgrp.CourseGroupId = crs.CourseGroupId) AS Category
FROM
Courses crs
INNER JOIN
CourseRequests creq ON crs.CourseId = creq.CourseId
WHERE
crs.Coursename <> '''')
Select *, (select COUNT(CourseId) from cte) AS Recordcounts
from cte
I am trying to create a stored procedure in order to insert some data into some table in Oracle 11g.
For this purpose, I need to read the last amount from the latest insert for that user, and then add it to my new value and save the changes as a new row and if any kind of exception is occurred just rollback. This is what I have come up with so far:
CREATE OR REPLACE PROCEDURE MYTESTDB.INSERT_INTO_TESTBANK
(
ID IN TBLTESTBANK.ID%TYPE,
USERID IN TBLTESTBANK.USERID%TYPE,
TYPE IN TBLTESTBANK.TYPE%TYPE,
AMOUNT IN TBLTESTBANK.AMOUNT%TYPE,
DATETIMESTAMP IN TBLTESTBANK.DATETIMESTAMP%TYPE,
TRANSACTION_ID IN TBLTESTBANK.IDTRANS%TYPE,
TOTAL_MONEY IN TBLTESTBANK.TOTALMONEY%TYPE,
COMPUTED_HASH IN TBLTESTBANK.HASH%TYPE
)
IS
BEGIN
DECLARE
LastAmount TBLTESTBANK.TOTALMONEY%TYPE;
BEGIN
SELECT TBLTESTBANK.TOTALMONEY INTO LASTAMOUNT
FROM
(
SELECT TBLTESTBANK.ID
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
)
where ROWNUM<2;
EXCEPTION WHEN NO_DATA_FOUND
THEN LastAmount := 0;
END;
LastAmount := LastAmount+ AMOUNT;
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, LastAmount,
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
VALUES (ID, USERID, TYPE, AMOUNT, DATETIMESTAMP, TRANSACTION_ID, TOTAL_MONEY, COMPUTED_HASH);
COMMIT;
EXCEPTION WHEN OTHERS
THEN
ROLLBACK;
END;
/
Whenever I try to test it, I get a red wiggly line under the first SELECT , and then he TESTBANK.ID in the inner select statements. For the select command it says, sql statement is ignored, and for the TESTBANK.ID it says invalid identifier!
It also doesn't let me add two variables, and keeps saying LastAmount must be declared.
And these are the errors I get :
Error(19,7): PL/SQL: SQL Statement ignored
Error(22,16): PL/SQL: ORA-00904: "TBLTESTBANK"."ID": invalid identifier
Error(32,3): PLS-00201: identifier 'LASTAMOUNT' must be declared
Error(32,3): PL/SQL: Statement ignored
Error(34,3): PL/SQL: SQL Statement ignored
Error(34,47): PL/SQL: ORA-00904: "LASTAMOUNT": invalid identifier
You have two problems:
In your select statement:
SELECT TBLTESTBANK.ID
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
You have given the table TBLTESTBANK the alias tblbnk therefor you must use the alias throughout the statement:
SELECT tblbnk.ID -- use the correct alias here
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
Second:
in the INSERT statement you have to list columns not values.
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, LastAmount,
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
should be:
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, AMOUNT, --- column name instead of variable name
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
And then of course you need to use LastAmount in the values part, not AMOUNT
In general it's not a good idea to have variables with the same name as columns of tables that you use in the procedure. It's easy to shadow a variable with a column. You should rename the variables to avoid any problems there.
Edit (I didn't notice this at first).
You also have an error in the structure of the code. A stored procedure (or function) does not have a DECLARE section:
Your declaration needs to look like this:
CREATE OR REPLACE PROCEDURE MYTESTDB.INSERT_INTO_TESTBANK
(
....
)
IS
-- no DECLARE
-- variables right after the IS keyword
LastAmount TBLTESTBANK.TOTALMONEY%TYPE;
BEGIN
...
END;
You can try below select query to get latest record.
SELECT TB.TOTALMONEY INTO LASTAMOUNT
FROM
TESTBANK TB
WHERE
TB.USERID=USERID
AND
DATETIMESTAMP= (SELECT MAX (TB2.DATETIMESTAMP) FROM TESTBANK TB2
WHERE TB2.USERID=USERID);