what does the "2"mean in SQL*Plus? - oracle

I am new to Oracle.
And I have come across a problem.
Firstly,I want to check the privileges of the sysman account:
SQL> select * from dba_sys_privs where grantee='sysman';
no rows selected
I know that it means there is no content in my view dba_sys_privs. But anyway,I have aready built a database. So, I try again, just shortening the statement:
SQL> select * from dba_sys_privs
2
So here are my two questions:
what happened to my database? I have already set up a database
what does the "2" mean? Does it mean the next row or something else?

You have entered a new line character (pressed return) without entering a statement termination i.e. ;. Compare your second statement with the first one you posted. So yes, the 2 means the client is awaiting further input.
To run the second statement, simply enter a slash /
As for why your first statement returned no rows, in Oracle database object names (including users) are in upper-case.
select * from dba_sys_privs where grantee='SYSMAN';

I encountered similar situaion due to my inserts did not work as expected. I used a insert statement followed by "commit;", it just says committed, but when I use sql developer to view the record, I could not find it. So I tried to run select from sqlplus and got a number.
Later DBA told me to skip the "commit", then I could see the exception thrown.

Related

Using CFQUERY and Returning a Recordset Using an Oracle Anonymous Block

Reference: Oracle SQL RETURN INTO Fails within CFQUERY (ORA-06550/PLS-00103)
Placing the PL/SQL into a variable then executing in a CFQUERY tag works, but when I dump the query variable, I get "Variable XX is undefined".
How do I get the anonymous block to return the id of the affected record, or better yet, the entire record?
Below is the code which executes, but throws the error...
<cfset plsql = "
DECLARE record_id scpricequeue.scpricequeueid%TYPE;
BEGIN
update scpricequeue
set datelocked = sysdate
where scpricequeueid = (
select scpricequeueid
from (
select scpricequeueid
from scpricequeue
where islocked = 0 and completed = 0
order by dateadded asc
)
where rownum <= 1
)
RETURNING scpricequeueid INTO record_id;
END;
">
<cfset sql = "
select *
from scpricequeue
">
<cfquery name="q" datasource="ecomd">
#plsql#
</cfquery>
<cfdump var="#q#">
ERROR: Variable q is undefined
I solved my specific need in another way, by using SELECT ... FOR UPDATE
When you issue a SELECT statement against the database to query some records, no locks are placed on the selected rows. In general, this is a wonderful feature because the number of records locked at any given time is kept to the absolute minimum: only those records that have been changed but not yet committed are locked. Even then, others are able to read those records as they appeared before the change (the “before image” of the data).
There are times, however, when you will want to lock a set of records even before you change them in your program. Oracle offers the FOR UPDATE clause of the SELECT statement to perform this locking.
When you issue a SELECT...FOR UPDATE statement, the database automatically obtains row-level locks on all the rows identified by the SELECT statement, holding the records “for your changes only” as you move through the rows retrieved by the cursor. It’s as if you’ve issued an UPDATE statement against the rows, but you haven’t—you’ve merely SELECTed them. No one else will be able to change any of these records until you perform a ROLLBACK or a COMMIT—but other sessions can still read the data.
Ref: Oracle PL-SQL by O’Reilly, Pg 492
However, I was also tracking down a couple other more complex but promising solutions. I never reached conclusion, but in the hopes that these are useful pointers for others, here they are.
Oracle Package/CF Stored Procedure: See section titled “Use Oracle referenced cursors to return result sets (ColdFusion 4.5+, Oracle 7.3+):” and “Oracle PL-SQL” (Chapter 18 on Packages). I just hadn't figured out how to create the package and link it to CF, but this seemed like it would definitely be a viable solution.
I was going to test to see if CFTRANSACTION puts a lock on a record, which would be similar to my SELECT...FOR UPDATE solution above.

OracleDatareader seems to execute an update statement

I am using oracle client 11.2.0
Dll version 4.112.3.0
We have a page in our application where people can give a sql statement and retreive results. basically do an oracle command.executereader
Recently one of my team members gave an update statement as a test and it actually performed an update on a record!!!!
Anyone who has encountered this?
Regards
Sid.
It is a normal (albeit a bit unsettling) behavior. ExecuteReader is expected to execute the sql command provided as CommandText and build a DbDataReader that you use to loop over the results.
If the command doesn't return any row to read is not something that the reader should prevent in any case. And so it is not expected that it checks if your command is really a SELECT statement.
Think for example if you pass a stored procedure name or if you have multiple sql batch to execute. (INSERT followed by a SELECT)
I think that the biggest problem here is the fact that you allow an arbitrary sql command typed by your users to reach the database engine. A very big hole in security. You should, at least, execute some analysis on the query text before submitting the code to the database engine.
I agree with Steve. Your reader will execute any command, and might get a bit confused if it's not a select and doesn't return a result set.
To prevent people from modifying anything, create a new user, grant select only (no update, no delete, no insert) on your tables to that user (grant select on tablename to seconduser). Then, log in as seconduser, and, create synonyms for your tables (create synonym tablename for realowner.tablename). Have your application use the seconduser when connecting to the DB. This should prevent people from "hacking" your site. If you want to be of the safe side, grant no permissions but create session to the second user to prevent him from creating tables, dropping your views and similar stuff (I'd guess your executereader won't allow DDL, but test it to make sure).

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

create large objects in oracle via sqlplus

I have a view whose DDL definition is many thousands of lines long. Part of our CI process is to drop and recreate views from DDL using SQLPlus called from a command line script.
This works for hundreds of views in the database but the very large view is never created in the target schema. I always manually paste the view creation script into Toad and run it manually after the automated process has completed. This is a drag.
There is no meaningful error message from SQLPlus when the large-view portion of the DDL script is run but I suspect that it fails because of it's size.
Is there a "set" command that I can include at the top of my DDL to tell SQLPlus that it's ok to create large views or am I forever doomed to include a stoopid manual step in the otherwise automatic CI process?
Firstly, use the most recent version of SQLPlus. Its been a long time since I had a piece of code that was too large to be executed through SQLPlus. You can use the InstantClient
I'd also look at re-factoring the view. Look at the WITH clause as that is relatively new and, if the view has evolved over a long period, there's a good chance it can be amended to make use of this
Is there an empty line in the view SQL, or does any line have more than 2499 characters? Either one of these may cause SQL*Plus to behave unexpectedly but not actually fail.
If there is an empty line, Oracle will ignore everything before it and try to run everything after it. (This only applies to SQL, not PL/SQL.) For example, if you have an empty line right after the create view line, the query will run:
SQL> create or replace view newline_in_the_middle as
2
SQL> select * from dual;
D
-
X
A line with >2499 characters will be ignored but Oracle will still try to process the statement without it. This can cause problems but may still result in a valid statement:
SQL> create or replace view long_line as
2 select '...[enter 2500 characters]...' asdf from dual union all
SP2-0027: Input is too long (> 2499 characters) - line ignored
2 select '1' asdf from dual;
View created.
You may have to check the script output very carefully to find these issues.

Strange Oracle problem

I tried to put it in a sentence but it is better to give an example:
SELECT * FROM someTable WHERE id = someID;
returns no rows
...
some time passes (no inserts are done to the table and no ID updates)
...
SELECT * FROM someTable WHERE id = someID;
returns one row!
Is it possible that some DB mechanism prevents first SELECT to return row?
Oracle log has no errors.
No transactions are rolled back when two selects are executed.
You can't see uncommitted data in another session. When did the commit happen?
EDIT1: Are you the only one using this database? Or did/do you have multiple sessions?
I think in another session you or someone else has inserted this row, you do your select and you don't see this row. After that a commit happens in the other session (maybe implicit because a session is closed) and then you see this row when you select again.
I can think of other explanations, but I first want to know are you only one using this database.
With read consistency as provided by Oracle, you should not see a row appear like that. If you are running in some mode with automatic commits, so that each statement is a self-contained transaction, then read consistency is not being violated. Which program are you using to access the database? I agree with the other observations; the row should not appear if your session is not inserting it and no other session is active at the same time. I don't know of a DBMS that indulges in spontaneous data generation.
Don't you have scheduled jobs in that Oracle?

Resources