How to view/execute granted stored procedure in Oracle SQL developer - oracle

The user that I use to access a particular DB has been granted EXECUTE privilege for a stored procedure managed by another user. Is there any way to view or run that stored procedure in Oracle SQL developer like a regular stored procedure? At the moment I don't see it in the Procedure tab in connections to right click and run. I am executing the stored procedure in java but I need to be able to test it in SQL developer.

The procedure won't appear in the tree list immediately under your connection, as those are only ever the ones that the user you are connected as owns themselves. (If you right-click and choose 'Filter', there is an option to 'override schema filter', but even with a filter and that flag set you don't see other users' procedures.)
But right at the bottom of the list of objects types under your connection is an 'Other Users' entry. If you expand that, find the owner of the procedure and expand that, and then expand the list of procedures under that user - you'll see all of their procedures that you have permission to view/execute.
You can then run it from there the same way you would run your own procedures.
You can also right-click on your connection and choose 'Schema Browser'; then in the tab that appears you can more easily change user, and change the object type to 'Procedures'. You might find that faster than navigating the tree.
#thatjeffsmith has a post about navigating via the tree or the dropdowns (of course - should have looked their first...)

If you have a procedure "test_procedure" in your shema you would execute it like this:
begin
test_procedure;
end;
If you have it in another schema, lets say "parent" then you would call it like this:
begin
parent.test_procedure;
end;

Related

SQLDeveloper - seeing and modifying procedure code in another schema

How can I see and modify procedure code in another schema? Right now I'm doing
select * from all_source
where name = 'MY_PROCEDURE'
But that's awful.
I think, the simplest way is to show a screenshot:
In the connections panel expand you connection so you can see the list of object types (tables, views, etc.). Scroll to the bottom of that list and you'll see the last entry is 'Other Users'. Expand that and find the owner of the procedure in that new sub-list. Expand that and scroll down their object type list, expand the 'Procedures' list, and double-click the name of the procedure you're interested in.
That will let you see the source code. To modify it you will need your DBA to grant you the appropriate privileges, if they think it's a valid thing for you to be doing.
If you already have access to the schema you can just create a new connection using that, which would make this simpler.

Running SQL within same session as my SQLDeveloper debugger

This seems an obvious requirement/use-case to me, but I haven't found anything online.
I'm debugging a PL/SQL Stored Proc which stores data in pseudo-temporary tables along the way (they are just regular tables, whose content is wiped at the end of the transaction). I'd like to inspect these values as I go. However, there seems to be no way to run arbitrary SQL within the same session that is debugging the stored proc. If I try select * from temp_..., I get no rows back and I can see that I have more than one connection open to the database.
Is there a way to do this?
I doubt there is a way to do exactly what you asked. How about either a) committing the rows you're working with, querying them from another session during debug, then truncating your table when finished or b) add a default false debug parameter to your stored proc, then output what you wish when it is set true.
There is a setting in PL/SQL Developer, called Session Mode.
Go to Tools->Preferences->Connection->Session Mode, then select 'Single session'.
When you switch to single session mode your pl/sql procedure and other connections on behalf of one user will reside within single session. So you will be able to execute sql during debug and inspect all the data you want to.

Is there a way to make Visual Studio 2010 database projects use DROP and CREATE instead of ALTER for DML

When building a deploy script for a Visual Studio 2010 SQL database project, is there any way to instruct the process to use DROP and CREATE for stored procedures and other DML instead of always ALTERing them?
As an example, if I change a stored procedure, the deploy script will generate something like this...
ALTER PROCEDURE MyProc
AS
SELECT yadda...
I want the deploy script to create something like this instead
IF EXISTS MyProc
DROP MyProc
CREATE PROCEDURE MyProc
AS
SELECT yadda....
It would make version controlled upgrade scripts a bit easier to manage, and deployed changes would perform better. Also if this is not possible, a way to at least issue a RECOMPILE with the ALTER would help some.
This question asks something that seems similar, but I do not want this behavior for tables, just DML.
I'm not familiar enough with database projects to give an answer about whether it's possible to do a DROP and CREATE. However, in general I find that CREATE and ALTER is better than DROP and CREATE.
By CREATE and ALTER I mean something like:
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME = 'MyProc'
AND ROUTINE_TYPE = 'PROCEDURE')
BEGIN;
-- CREATE PROC has to be the first statement in a batch so
-- cannot appear within a conditional block. To get around
-- this, make the statement a string and use sp_ExecuteSql.
DECLARE #DummyCreateText NVARCHAR(100);
SET #DummyCreateText = 'CREATE PROC dbo.MyProc AS SELECT 0;';
EXEC sp_ExecuteSql #DummyCreateText;
END;
GO
ALTER PROCEDURE dbo.MyProc
AS
SELECT yadda...
The advantage of CREATE and ALTER over DROP and CREATE is that the stored proc is only created once. Once created it is never dropped so there is no chance of permissions getting dropped and not recreated.
In a perfect world the permissions on the stored proc would be applied via a database role so it would be easy to reapply them after dropping and recreating the stored proc. In reality, however, I often find that after a few years other applications may start using the same stored proc or well-meaning DBAs may apply new permissions for some reason. So
I've found that DROP and CREATE tend to cause applications to break after a few years (and it's always worse when it's someone else's application that you know nothing about). CREATE and ALTER avoids these problems.
By the way, the dummy create statement, "CREATE PROC dbo.MyProc AS SELECT 0" , works with any stored procedure. If the real stored procedure is going to have parameters or return a recordset with multiple columns that can all be specified in the ALTER PROC statement. The CREATE PROC statement just has to create the simplest stored procedure possible. (of course, the name of the stored proc in the CREATE PROC statement will need to change to match the name of your stored proc)

Insert, delete ,update when using Stored Procedure component

We have an application written in Delphi 2010 which connects to SQL Server Database. Now we're in the process of migrating to Oracle. With SQL Server it was very easy to perform insert, update, delete right from a dbgrid connected to a Stored Procedure.
It's because stored procedures in SQL Server can easily act as a table so that you can do any operation on it, providing it returns the necessary columns within the resultset. Now with Oracle I don't know how do do it. I connect a DBGrid to a DataSource, dataset of which is a Stored Procedure object,but I can't edit the grid. Just Select is possible.
What do I have to do to to achieve this?I use UniDac component suite to connect to Oracle database.
Oracle does not support such functionality. IOW, in Oracle you cannot edit result set provided by a stored procedure or include stored procedure into INSERT INTO <name>, UPDATE <name> or DELETE FROM <name>.
While it is traditional for SQL Server developers to "always" use stored procedures (due to many reasons), it is not traditional for Oracle developers. But it is possible with Oracle too. Search for "REF CURSOR" to see how to fetch data using SP. And use normal or packaged (preferred) SP to post updates to a DB. These procedure will receive old / new field values through arguments.
I cannot say precisely about UniDAC, I can say about AnyDAC. But I will expect UniDAC has similar functionality. To use SP for posting updates you will need to use TXxxUpdateSQL component.
OK,here I'm answering the question though I can see very few are dealing with Delphi recently. Let's say we have a stored proc in Oracle database:
CREATE OR REPLACE PROCEDURE GET_EMPLOYEES
(V_CUR IN OUT SYS_REFCURSOR)
AS
BEGIN
OPEN V_CUR FOR SELECT * FROM EMPLOYEES;
END GET_EMPLOYEES;
Now, in Delphi you pick a stored procedure component (probably from ODAC or UniDac component suite).Set its StoredProcName GET_EMPLOYEES. Then you can add all the fields that the procedure returns in a cursor.If you run the application and activate the stored procedure you'll be able to see all the records. But if you try to insert, modify or delete anything you'll fail to do so. Now, there's a very tricky thing. If you check, you'll see that ReadOnly property of all fields are set to True. Even after you set them to False nothing will change in the real database, although you can edit the DBGrid.
So, we've come to the main part. How did the old Delphi-SQL Server partnership work so that you could do any operation right from a DBGrid? Well, we must understand that there's no magic. If it's SQL, then SQL has only one way of INSERTING,UPDATING and DELETING records-it's with the appropriate SQL statements.With Delphi-SQL Server there seems to be an implicit SQL statement that we never paid attention. But with Oracle, we have to provide our own statements for each operation.
If you use UniDac or ODAC then there's SQLInsert,SQLUpdate,SQLDelete properties in a StoredProc object.If you want to insert a record through DBGrid, then you should edit its SQLInsert property to
INSERT INTO EMPLOYEES VALUES(:EMPLOYEEID,:EMPLOYEENAME)
where variables following : are corresponding to te fields of the stored procedure.They're simply bind variales.When updating and deleting though you'll need some unique value to represent a specific record. Primary key is one option(maybe the only option as I haven't been able to figure out how to use ROWID for the same purpose).So the sql statements for UPDATE and DELETE would be
DELETE FROM EMPLOYEES WHERE EMPLOYEEID=:EMPLOYEEID
and
UPDATE EMPLOYEES SET EMPLOYEENAME=:EMPLOYEENAME WHERE EMPLOYEEID=:EMPLOYEEID
P.S. I just found a way to use ROWID for update and delete statements. In your stored procedure if you choose ROWID too and give it an alias then you can construct your UPDATE and DELETE Statements like such:
UPDATE EMPLOYEES SET EMPLOYEENAME=:EMPLOYEENAME,..... WHERE ROWID=:RECORD_ROWID
DELETE FROM EMPLOYEES WHERE ROWID=:RECORD_ROWID
In the preceding statements RECORD_ROWID is the fieldname returned from stored procedure as a result of aliasing ROWID. If you use :ROWID instead you'll get "ORA-01745: invalid host/bind variable name" error. This is because in a binding variable a colon cannot be followed by a reserved word. And ROWID is a reserved word.

Logging stored procedure access in Oracle

Is there an convenient way to log access to stored procedures from withing Oracle? I am a web developer and presently we are required to pass a variety of user info to many stored procedures so that those procedures can in turn call another procedure that logs access to the original stored procedure in a table.
For example if I want to call a procedure called get_movie(id) that will return a row from the movie table based on id, I would have to do something like this get_movie(username, domain, ip, id) so that the procedure can log the user/domain/ip of the web user who initiated the call to the procedure.
It seems like there must be a better way but my knowledge of Oracle is limited.
I would set the common parameters using a procedure and sys_context every time you get your connection
e.g:
CREATE OR REPLACE PROCEDURE set_context
(
v_userid IN VARCHAR2,
v_domain IN VARCHAR2,
v_ip IN VARCHAR2,
v_id IN VARCHAR2
)
AS
BEGIN
DBMS_SESSION.SET_CONTEXT('SESSIONCONTEXT', 'username', v_userid);
DBMS_SESSION.SET_CONTEXT('SESSIONCONTEXT', 'domain', v_domain);
DBMS_SESSION.SET_CONTEXT('SESSIONCONTEXT', 'ip', v_ip);
DBMS_SESSION.SET_CONTEXT('SESSIONCONTEXT', 'id', v_id);
END;
and to query the values:
SELECT SYS_CONTEXT('SESSIONCONTEXT', 'username') FROM dual;
see: http://download.oracle.com/docs/cd/E14072_01/server.112/e10592/functions182.htm
and
Is there a way to communicate application context to a DB connection in non-Sybase DB servers (similar to set_appcontext in Sybase)?
It is probably impossible to do that. (warning many assumptions upcoming)
Primarily because the user from oracle's perspective is probably whatever user is connecting from your application to the database. Oracle certainly knows about the user connecting, but I would venture to guess that most if not all of your queries to the db are done through a single user configured in a properties file somewhere.
That is why these values need to be passed in, because the application has a connection to those users and can know their ip. However, the db doesn't as it is (hopefully) sectioned off from users connecting directly.
Other option is to open an oracle user for every "end user" and grant them access to the schema where the business logic is. USe public synonyms.

Resources