Oracle basic multi-statement block - oracle

In SQL Server, multiple statements in SSMS can be performed. In Oracle (using toad), I don't know why I receive certain errors doing the same thing. For example, I assume an Oracle requirement is to place them in a block, but I still get the following:
DECLARE
v_datetime TIMESTAMP := SYSDATE;
BEGIN
insert into sometable_log values (v_datetime, 'this is a test ',1);
select * from sometable_log where event_dt = v_datetime;
END;
produces:
[Error] Execution (5: 1): ORA-06550: line 4, column 1: PLS-00428: an
INTO clause is expected in this SELECT statement
Why would I need to use an into clause? Can someone please help me understand what this is?
Thank you!

When executing the block of code, Oracle expects that the select command should have some code-like effect. That's why it wants you to add the into clause.
To do what you need, just move the select statement outside of the PL/SQL begin/end block.

Related

Running PL/SQL script in PHP

I have a script in PL/SQL , that drop some tables , sequences , triggers, and creating them again in the same script , I need this script in my website for deleting all data from database (and I want to acces this script pressing one button on website) so I tried to do a function / procedure in PL/SQL that read line by line from the script file and executing every line with dynamic sql , everything went ok till one error at:
CREATE OR REPLACE TRIGGER players_bir BEFORE INSERT ON players FOR EACH ROW BEGIN SELECT players_seq.NEXTVAL INTO :new.id FROM dual END
this gave me the error:
ORA-24344: success with compilation error
I searched for solutions, but I didn't find anything.
You are missing the semi-colon after dual on your SELECT statement. This ORA error generally means you compiled some code, but that is has some issue.
CREATE OR REPLACE TRIGGER players_bir
BEFORE INSERT ON players
FOR EACH ROW
BEGIN
SELECT players_seq.nextval
INTO :new.id
FROM dual;
END
Looking in all_errors will show you what the issue is or you could manually compile this trigger in some IDE (like SQL Developer) and that should also make it obvious.
SELECT *
FROM all_errors e
WHERE e.name = 'PLAYERS_BIR'
AND e.type = 'TRIGGER';
Additionally if all you are using your trigger for is to set some identity column and you are on Oracle 12c you can use some of the new features to accomplish this. Triggers are inherently slow and the new identity feature performs about as good as referencing the sequence directly in your INSERT.

SYS_REFCURSOR out parameter - running stored procedure fails

I come from a SQL Server background but I'm struggling with this in Oracle. All of the sprocs in the database that's been configured expect a parameter passed in of type 'sys_refcursor'. In a nutshell, they do this (the sprocs are far more complex, but the whole cursor thing is what I'm getting at) :
CREATE OR REPLACE PROCEDURE xxx_API_TEST
(
TESTCURSOR OUT SYS_REFCURSOR
) AS
BEGIN
OPEN CURS FOR
SELECT * FROM SOMETABLE;
END xxx_API_TEST;
So - in Oracle SQL Developer I can run this no problem - and view the output of the cursor in the Output Variables window.
However, rather than have to keep reloading the dialog each time I want to retest it - I figured it'd be possible to copy the PL/SQL in the dialog to a new worksheet, and then just run that as I needed to - adjusting parameters to suit - so in this case, I'd run :
DECLARE
TESTCURSOR SYS_REFCURSOR;
BEGIN
xxx_API_TEST(
TESTCURSOR => TESTCURSOR
);
/* Legacy output:
DBMS_OUTPUT.PUT_LINE('TESTCURSOR = ' || TESTCURSOR );
*/
:TESTCURSOR := TESTCURSOR; --<-- Cursor
--rollback;
END;
Which is exactly the same as that shown in the Run dialog.
However, if I do this - it just throws an error - stating:
Error starting at line : 1 in command -
<snip>
Error report -
ORA-06550: line 11, column 20:
PLS-00382: expression is of wrong type
ORA-06550: line 11, column 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I've no idea how to go about diagnosing this one. The fact it runs fine from the dialog but not the worksheet is puzzling - and inspecting what was sent to the DB I can't see any differences in the SQL it actually used.
Interestingly if I run this code from the worksheet - it pops up a dialog to ask for the value for TESTCURSOR - which the 'Run' dialog doesn't do. I just press OK - but I've tried both ticking and unticking the 'Null' checkbox to no avail.
Any help very much appreciated. It's Oracle 12c. If you need any more info just let me know.
Cheers,
Tony
Update: 20/7/2016
I ended up pulling the values into variables from a fetch, and just dumping to dbms_output - which gives me what I needed to repeatedly run the same sproc.
e.g.
loop
fetch testcursor into Res, ActDate<snip>;
exit when testcursor%notfound;
DBMS_OUTPUT.PUT_LINE(Res || ' | ' || ActDate etc etc);
end loop;
close testcursor;
The Run dialog is generated from the procedure spec and therefore knows the correct type for testcursor, but when you just paste it into a worksheet it doesn't, and it seems to define it as a text string. As of SQL Developer 4.0.3.16 the worksheet bind value prompt doesn't seem to have a way to change the datatype.
As for how to create a reusable test script with a cursor output in SQL Dev, I don't know. (I normally use PL/SQL Developer which can do this, but it's not free software.)
Edit: in this thread a solution was to write a wrapper function and select it from dual. I've just tried and you don't get a grid, but you get a kind of debug output without too much effort:
Oracle SQL Developer: Show REFCURSOR Results in Grid?

Error in select query in Oracle

I've used a select statement in stored procedure in oracle 11g xe.But an error is showing as
pls-00428-an INTO clause is expected with select statement
I just cannot understand the error.When i searched i found out that in pl/sql an into clause is needed.I'm using toad.But when i used sql editor same error is showing.
Here's my procedure
CREATE OR REPLACE PROCEDURE ACTSINFO.sp_Get_WorkDetails
IS
BEGIN
select * from workdetails;
END sp_Get_WorkDetails;
Oracle is different from Microsoft SQL Server and therefor returning a result set from a procedure (or function) is different as well.
What you are looking for is a "pipelined table function".
Please refer to the manual for a description and an example:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/tuning.htm#i53109
Here are some more examples from other sites:
http://www.oracle-developer.net/display.php?id=207
http://www.oracle-base.com/articles/misc/PipelinedTableFunctions.php
http://psoug.org/reference/pipelined.html
You are trying to write wrong syntax or improper use of SELECT statement. You have to either create a cursor or use SELECT .. INTO syntax to set scalar value to the local variables.

Get the Affected Row from PL-SQL

I am using ODP.Net and run the PL/SQL Command to merge the table in the Oracle 10G database.
My command is as follow:
MERGE INTO TestTable t
USING (SELECT 2911 AS AR_ID FROM dual) s
ON (t.AR_ID = s.AR_ID)
WHEN MATCHED THEN
UPDATE SET t.AR_VIUAL_IMPAIRMENT = 1
WHEN NOT MATCHED THEN
INSERT (AR_S_REF)
VALUES ('abcdef');
SELECT sql%ROWCOUNT FROM dual;
The Merge command runs successfully and update/insert as I want. The problem is I want to know how many records are updated.
When I run the above statement, "ORA-00911: invalid character error".
Please advise me how I could get the affected rows back. Thanks million.
You're mixing up a few things: a MERGE statement is a plain SQL command while PL/SQL code is always delimited by BEGIN/END (and optional DECLARE). Furthermore, SQL%ROWCOUNT is a PL/SQL variable that cannot occur outside of PL/SQL.
And I don't quite understand whether you ran the MERGE and the SELECT statement with two separate or a common ODP.NET call.
Anyway, the solution is straightfowrad with ODP.NET: Execute the MERGE command with OracleCommand.ExecuteNonQuery(). This method returns the number of affected rows.
One thing you could do is put your code in a PLSQL function that returns %ROWCOUNT.
Then call this function from ODP.net setting the command type to stored procedure and using the ExecuteLiteral method which is going to return you the row count as an object instance you can cast as an int.
It is not possible to return just the "updated" row count.
(as already mentioned the row count is the number of affected (inserted and updated) rows)
there is a good discusion on ask tom: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:122741200346595110

How to make Oracle error messages more verbose?

The message that drives me crazy is ORA-01008 - Not all variables bound.
Is there a way to know which one of the 42 possible variable names I have misspelled without staring at the monitor till my eyes pop out?
Update: I use ADO.NET to access the database. Perhaps it does lose some information in Oracle exceptions, as #Justin Cave has suggested. But I'm positive that the parameter name never appears even in SQL Plus.
In general, Oracle provides the line and column number of any errors, but it is up to the particular API you are using (unless you happen to be writing an OCI application, which is probably unlikely) as to whether and how those APIs are called. Since the answer is likely to end up being API-specific, what API are are you using and what does your code look like when the error occurs (i.e. JDBC, ODBC, OLE DB, etc)?
As an example, if I write a PL/SQL block with a misspelled variable name, SQL*Plus will report the line and column number of the error in addition to the error message. Many APIs, on the other hand, will just report the PLS-00201 error by default.
SQL> declare
2 i integer;
3 begin
4 j := 1;
5 end;
6 /
j := 1;
*
ERROR at line 4:
ORA-06550: line 4, column 3:
PLS-00201: identifier 'J' must be declared
ORA-06550: line 4, column 3:
PL/SQL: Statement ignored
Similarly, if you execute a SQL statement with an invalid variable name, SQL*Plus will get the column and line position and put a * under the offending character, i.e.
SQL> create table a( col1 number );
Table created.
SQL> insert into a( colN ) values ( 1 );
insert into a( colN ) values ( 1 )
*
ERROR at line 1:
ORA-00904: "COLN": invalid identifier
Most PL/SQL IDE's (TOAD, SQL Developer, etc.) will do something similar by interrogating the appropriate OCI APIs under the covers. Precisely how this is done, however, will depend on the API.
I don't know of any way to get Oracle to make the error more specific. Maybe some future version will improve this error message.
Instead of just staring at it, though, there are other things you can try. For example, convert each variable in the SQL statement to a literal one at a time, until the error goes away. If possible, generate the list of variable names instead of typing them manually.

Resources