Calling a Function Using DB Link in Oracle - sql

I have a function (takes 2 parameters) that exists in my source DB and I am trying to call it from another DB using a DB Link. I am using the following code but I keep getting an error:
SELECT SCHEMA.FUNC_NAME#DBLINK(PARAM1, PARAM2) FROM SCHEMA.TABLE_NAME#DBLINK;
And here is the error I am getting:
ORA-00904: "SCHEMA"."FUNC_NAME": invalid identifier

I am going to rename your database references in my attempt to answer your question.
I will use localDB and remoteDB as database names.
You have a function created on remoteDB.
You should have the DBlink created on localDB. In the DBLink definition, you have owner, db_link, username, host, and created date.
On the remoteDB, you need to give select and maybe execute privileges to the username specified in your dblink.
Then, you should be able to execute the function from the localDB using some syntax such as EXEC SQL CALL schema.func_name#dblink(parm1, parms);

Related

SQL Server database: Can't find an object which clearly exists

EDIT: How to give exec permissions to a user defined type?
Looks like "Bug2" is a user defined type.
select * from sys.types
where is_user_defined = 1 and name = 'Bug2'
Now to get rid of this error:
"The EXECUTE permission was denied on the object 'Bug2', database
'abc', schema 'dbo'"
What command should I be using?
I'm just playing around with someone else's code and bumped into this:
If I do
DECLARE #bugList Bug2
SELECT *
FROM #bugList
Then I'm getting results
But if I do
SELECT *
FROM Bug2
Then I get a
Invalid object name 'Bug2'.
What is going on here?
Basically I'm trying to run a stored procedure which uses this "Bug2" and since there is some permission issue I'm getting this error on running it:
The EXECUTE permission was denied on the object 'Bug2', database 'abc', schema 'dbo'.
So all I want to do is:
GRANT EXEC ON Bug2 TO PUBLIC
But SQL Server is not able to find this object "Bug2" and therefore throws an error.
Can anyone help?
Ok. Got it working using this:
GRANT EXECUTE ON TYPE::Bug2 to PUBLIC
Thanks!
Instead of using sys.types use sys.objects. If Bug2 is a table then query looks like:
SELECT * FROM sys.objects WHERE name='Bug2' AND type='U'
It's a user-defined table type (typically used for table-valued parameters). Look in db_nm > programmability > types > user-defined table types and you'll see a bug2 object. You can address the permissions issue on that object (via script or GUI).
Script Option:
use [abc]
GO
GRANT EXECUTE ON TYPE::[dbo].[bug2] TO [public]

Getting the name of the user who executed the Stored Procedure

I know this can be done in code (C#) by using WindowsIdentity, but is there a way to do this within the SP itself?
I tried using the USER function but it's returning dbo instead of the name. Is this because the user is the owner of the database? If that's so, how can I get the db owner's login name?
EDIT:
The application that executes the SP uses the sa user account, so if I use SYSTEM_USER, the returned value is sa.
SELECT SYSTEM_USER
Will return name of user which excecute code in SQL. More in this aricle
If SQL server service work from sa there is no way to get (windows) username from SQL Server side. I suppose it is security issue. Most information about connection to your SQL Server you may get from table sys.dm_exec_connections. There are stored IP addreses and port s and other useful things for existings connections.

SELECT data from another schema in oracle

I want to execute a query that selects data from a different schema than the one specified in the DB connection (same Oracle server, same database, different schema)
I have an python app talking to an Oracle server. It opens a connection to database (server/schema) A, and executes select queries to tables inside that database.
I've tried the following :
select ....
from pct.pi_int, pct.pi_ma, pct.pi_es
where ...
But I get:
ORA-00942: table or view does not exist
I've also tried surrounding the schema name with brackets:
from [PCT].pi_int, [PCT].pi_ma, [PCAT].pi_es
I get:
ORA-00903: invalid table name
The queries are executed using the cx_Oracle python module from inside a Django app.
Can this be done or should I make a new db connection?
Does the user that you are using to connect to the database (user A in this example) have SELECT access on the objects in the PCT schema? Assuming that A does not have this access, you would get the "table or view does not exist" error.
Most likely, you need your DBA to grant user A access to whatever tables in the PCT schema that you need. Something like
GRANT SELECT ON pct.pi_int
TO a;
Once that is done, you should be able to refer to the objects in the PCT schema using the syntax pct.pi_int as you demonstrated initially in your question. The bracket syntax approach will not work.
In addition to grants, you can try creating synonyms. It will avoid the need for specifying the table owner schema every time.
From the connecting schema:
CREATE SYNONYM pi_int FOR pct.pi_int;
Then you can query pi_int as:
SELECT * FROM pi_int;
Depending on the schema/account you are using to connect to the database, I would suspect you are missing a grant to the account you are using to connect to the database.
Connect as PCT account in the database, then grant the account you are using select access for the table.
grant select on pi_int to Account_used_to_connect

Oracle: Using a database link in a stored procedure : table or view does not exist

I currently have an issue whereby I cannot reference a table in a linked database within a stored procedure. I get the error message:
ORA-00942: table or view does not exist
Here are the steps I took on the host machine (running oracle 10g) to set up the database link to the remote database (running oracle 11g). The steps are accurate, but some some names have been changed, though they have been kept consistent.
Update tnsnames.ora, adding a new entry:
REMOTE_DB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)
(HOST = 10.10.10.10)
(QUEUESIZE = 20)
(PORT = 1521)
)
(CONNECT_DATA =
(SERVICE_NAME = remote_service)
)
)
Create database link, as the user who will later be creating and executing the stored procedure:
create database link remote_link
connect to "remote_user"
identified by "remote_pass"
using 'REMOTE_DB';
Prove database link is working by selecting from it:
select id from remote_table#remote_link;
id
--------------------------------------------------------------------------------
8ac6eb9b-fcc1-4574-8604-c9fd4412b917
c9e7ee51-2314-4002-a684-7817b181267b
cc395a81-56dd-4d68-9bba-fa926dad4fc7
d6b450e0-3f36-411a-ba14-2acc18b9c008
Create stored procedure that depends on working database link:
create or replace
PROCEDURE test_remote_db_link
AS
v_id varchar(50);
BEGIN
select id into v_id from remote_table#remote_link where id = 'c9e7ee51-2314-4002-a684-7817b181267b';
dbms_output.put_line('v_id : ' || v_id);
END test_remote_db_link;
Explode own head after staring at the following error message for over an entire working day:
Error(10,27): PL/SQL: ORA-00942: table or view does not exist
I have tried many things to try to sort this issue out, including:
When creating the database link, not using quotes around the username and password. Link creates fine, but selecting from it gives me this error:
ERROR at line 1:
ORA-01017: invalid username/password; logon denied
ORA-02063: preceding line from TWS_LINK
Tried various combinations of username and password in upper/lowercase. Received same error as 1.
Tried single quotes instead of double quotes around username and password. Recieved this error:
ERROR at line 1:
ORA-00987: missing or invalid username(s)
Proved I have full access to the remote db by connecting into it with sqlplus:
[oracle]$ sqlplus remote_user/remote_pass#REMOTE_DB
SQL*Plus: Release 10.2.0.1.0 - Production on Thu Oct 20 22:23:12 2011
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
I'm not sure what to do next. The possible next step is to start looking at issues on the remote database, and perhaps see if other databases can connect to it. Another would be to look at incompatibilities going from host 10g to remote 11g.
OK so I was able to get this working, of sorts.
It turns out that when creating the database link, the double quotes around the username and password fields were causing the issue. To summarise:
If they were present, and the link created as so:
create database link remote_link
connect to "remote_user"
identified by "remote_pass"
using 'REMOTE_DB';
The remote database could be queried via sql
The stored procedure could not be compiled, recieving the ORA-942 error
As the procedure could not be compiled, it could not be executed
When the double quotes are not present:
create database link remote_link
connect to remote_user
identified by remote_pass
using 'REMOTE_DB';
The remote database could not be queried via sql, recieving an invalid password error (detailed in the question)
The stored procedure could be compiled with no errors.
The stored procedure executes as expected, retrieving data from across the database link, and displaying it.
So, even though the remote database cannot be querued via sql, recieving an invalid password error, the procedure that uses this same connection information compiles and executes normally.
I'm sure you'll agree, this is a curious state of events, and I genuinely stumbled across making it work in my scenario. I'm not quite sure I would call it a solution, as there are plenty of unanswered questions.
Hopefully if someone comes here via google, they'll find this answer useful, and at least get their code running.
GC.
I faced the same issue on 11gR2, and I'm thankful to this forum for helping me find the problem. The way to make the db link work in both SQL and procedure is to follow the below syntax (enclose only the password within double quotes).
create database link remote_link
connect to remote_user
identified by "remote_pass"
using 'REMOTE_DB';
I think I see a problem here. Is the user who is executing the stored procedure the same user who created the stored procedure?
You said, "Create database link, as the user who will later be executing the stored procedure".
If the user creating the database link is different from the user creating the stored procedure, that may be your problem.
Try creating the stored procedure and database link as the same user, or creating a public database link.
Then, since Oracle default is definer rights, you can have anyone execute the stored procedure (assuming they have been granted execute privilege on the procedure).

Facing an error : table or view does not exist

I am using insert statement and trying to insert data into the database table. I am using stored procedures.
But I am getting this error while doing so.
Message: ORA-00942: table or view does
not exist ORA-06512
I checked if the tables/stored procedures are present or not and everything is in place. Also there is no typo in table names or in sp. If I run the part of SP from query editor it works fine but when I execute the entire SP it throws an error.
I tried the steps provided by Stephen but since I have logged in with the same user/owner when I run Grant command it gives me an error saying 'Cannot Grant/revoke on own'.
One more addition to this. I have a stored procedure SP1 in which I am using a select statement as
Select a from table_name where condition;
When I execute this seperately, it returns me some results. But when I execute sp it gives an error at the same line where it is written.
Can anyone help me out to resolve this issue. I am using SQL +.
Thanks in advance
Vijay
Justin's answer is correct but let me expand a bit.
Everyone who said that the table doesn't exist didn't read your whole post. Since you are able to:
If I run the part of SP from query editor it works fine
Obviously the table is there.
Obviously you have some access to it. Otherwise this wouldn't work when it clearly does.
but when I execute the entire SP it throws an error.
This is because Oracle distinguishes between permissions granted directly and those granted via a role.
Say I do this:
Create Table TABLE_A
Create Role READ_ONLY
Grant Select on TABLE_A to READ_ONLY
Grant READ_ONLY to VIJAY
In a SQL Window/prompt you could query that table without issue. So now you need to create a view
Create VIJAY.VIEW_A as SELECT * FROM TABLE_A
You'll get the error that TABLE_A does exist. Because a view is compiled, like a procedure it runs without any roles. Since it runs without the READ_ONLY role, it's blind to the fact that TABLE_A exists. Now what I need to do is
Grant Select on TABLE_A to VIJAY.
Now that you have a direct permission, you can compile a view or procedure/package that uses that table.
Does the table exist in the schema where the stored procedure exists? If not, the simplest explanation is that the owner of your procedure has been granted access to the table via a role not via a direct grant. A definer's rights stored procedure needs to have direct access to the objects it accesses. A quick way to test this is to disable roles for the session, i.e.
SQL> set role none;
SQL> <<execute your query>>
If that generates the error, the problem is the lack of a direct grant.
In Oracle you can choose if the stored procedure is executed with the rights of the invoker or the definer: http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17126/subprograms.htm#i18574
Check if the AUTHID property of the stored procedure is correct and if the resulting user has appropriate permissions.
Well, put very simply, the table that you are trying to insert data into does not exist in the database you are connected to. You need to check both those things (i.e. what are you connected to, and is the table there and accessible for the user context you are using).
As Joe Stefanelli said .. there are a lot of possibilities for the error being shown here.
Check whether:
You are connecting to the correct Oracle Instance.
You have permissions to query or perform processing on table that you are referencing in your query.
There is a difference between ordinary select statements and procedures. Procedures in oracle do not respect the roles assigned to a user; rather the permission needs to be explicitly granted to the user. For more information read the following linkORA-00942