What's the meaning of #! in Oracle DB? [duplicate] - sql

Looking at V$SQL in my database, I have just found a strange query that looks like :
UPDATE "MYTABLE" "A1" SET "SOMECOLUMN" = (
SELECT "A2"."ANOTHERCOLUMN"
FROM "ANOTHERTABLE"#! "A2"
WHERE "A2".ROWID=:B1
)
Does anyone know the meaning of the syntax #!
I have never seen something like it before in Oracle
Thanks

It's a query that has originated on a remote database. The database where you've seen this query in V$SQL has been referenced in the query on the remote database using the #DB_NAME syntax
The remote database has pushed the query to your database for execution, but to answer the query, your database needs to pull some information back from the remote database. This is where the #! comes in, basically it's a reference back to the database where the query originated from
For example, create a test database link, even to the same database, and run this:
alter system flush shared_pool;
select sysdate from dual#myself;
select sql_text from gv$sql where sql_fulltext like '%#!%';
SQL_TEXT
--------
SELECT SYSDATE#! FROM "DUAL" "A1"

Often # in databases are related to a database link.
E.g. in Oracle I use
create public database link
mylink
connect to
remote_username
identified by
mypassword
using 'tns_service_name';
if the after this user (remote_username) has a table ANOTHERTABLE you could use:
SELECT "A2"."ANOTHERCOLUMN"
FROM "ANOTHERTABLE"#mylink "A2"
WHERE "A2".ROWID=1
How the ! sign is used here is unclear for me. Normally the ! sign is something you use to access the shell where your database client is running.
I don't know is this helped you. Good luck.

Related

How to get the Oracle sql Id in the application

I have a .net web service that makes some dynamically generated sql calls against ORACLE and they are performing bad in production. The DBAs keep asking for the sql ids to tune the query. They can use the OEM tool to find the slow performing query and get the sql id. But I was wondering if there is a way to know the sql id and log it so that I can retrieve it and give it to the DBAs for tuning.
Is this something that can be achieved in .net ?
Query the V$SQL dynamic view to get the SQL ID;
More on the V$SQL:
https://docs.oracle.com/cd/B19306_01/server.102/b14237/dynviews_2113.htm#REFRN30246
The following package dbms_application_info is very useful to instrument your queries.
Prior to running the processing logic from app layer, set the module/action, to identify your module.
DBMS_APPLICATION_INFO.set_module(module_name => 'add_order',
action_name => 'processing orders');
After that, set the client_info with a marker that indicates what processing is going on prior to running the sql.
Eg:
exec dbms_application_info.set_client_info('starting load from staging');
--Run the query
insert into dest_table select * from staging;
update dest_table set last_updated=sysdate;
exec dbms_application_info.set_client_info('updated the last_updated column');
delete from dest_table where order_value<0;
exec dbms_application_info.set_client_info('deleted -ve orders');
When this happens we can have a look at v$session/v$sql to see where the processing is currently taking place
SELECT sid,
serial#,
username,
osuser,
module,
action,
client_info
FROM v$session
WHERE module='add_order'
SELECT *
FROM v$sql
WHERE module='add_order'
have a look at the link
https://oracle-base.com/articles/8i/dbms_application_info
If the application can capture sufficient information to identify the session in v$session, you can query it from another session to grab the value of sql_id, or else query the v$sql_monitor view if you are licensed (requires Enterprise Edition and the Diagnostics and Tuning option). Use dbms_application_info to tag activity for better tracking.
Also you can configure database services if you haven't already, so that applications connect to a specific service rather than a generic one, and this will appear in v$session.service_name and be reported in OEM etc.
If it's practical to capture the session details from the same session immediately after the poorly-performing SQL statement completes (which it may not be, if the connection times out for example), you might try querying the prev_ details from v$session:
select s.prev_sql_id
, s.prev_child_number
, s.prev_exec_start
, s.prev_exec_id
, p.sql_text as prev_sql
, p.plan_hash_value as prev_plan
from v$session s
left join v$sql p on p.sql_id = s.prev_sql_id and p.child_number = s.prev_child_number
where s.audsid = sys_context('userenv', 'sessionid')

Compare procedure Definition within two databases

We have an instance of Sql Server 2012,
In the Instance we have 2 dbs called A and B ( Assume A as production DB and B as Development DB and B is the exact copy of Database A )
suppose For Development Purpose,Some procedure ( Already Existed,Not Newly Created ) definition were changed in database B but not in A ( Production database ).
In order to Find the Procedures that are different by Definition i have came up with the following scenario,But the Problem is i not 100% Sure that this scenario works every time.
So please Suggest Your ideas On this.
Scenario
Temporary Table 1 ( A_PROCEDURE ) -- To Hold all the procedure name and Definition exists in database A ( Executed from Database A )
select * into A_PROCEDURE FROM (
Select routine_name,routine_definition from INFORMATION_SCHEMA.ROUTINES ) DTL;
Now From Database B i have Executed following Query To find All the Procedure Which are Not same by the Procedure Definition
SELECT T.ROUTINE_NAME B_PROC,
L.ROUTINE_NAME A_PROC,T.ROUTINE_DEFINITION B_PROC_DEF,L.ROUTINE_DEFINITION A_PROC_DEF
FROM INFORMATION_SCHEMA.ROUTINES T JOIN A.DBO.A_PROCEDURE L ON T.ROUTINE_NAME = L.ROUTINE_NAME
AND T.ROUTINE_DEFINITION <> L.ROUTINE_DEFINITION;
From the above Query i have found Procedures which are same by name But Not same by definition ( Which are Correct -manually Checked Line By line ).
So is this a proper way ? Should Consider anything else ? Please Share your ideas on this
Thanks and Best Regards,
Vishnudas
Hi Vishnudas: You need sp_HelpText system stored procedure. This utility stores the definition of every stored procedure in a SQL Server database engine.
It's worth for every DBA or developer to use a comparison tool. In the meanwhile, you can check this blog where you could write a script without stats about the in-line comparison of two stored procedures. There, you get an explanation about the use of sp_HelpText.
However, I suggest to use a comparison tool like SQL Compare tool, used by production teams in some middle and large companies. An useful top list is recommended and it was reviewed by another peers.

Exclamation mark in SQL (Oracle)

Looking at V$SQL in my database, I have just found a strange query that looks like :
UPDATE "MYTABLE" "A1" SET "SOMECOLUMN" = (
SELECT "A2"."ANOTHERCOLUMN"
FROM "ANOTHERTABLE"#! "A2"
WHERE "A2".ROWID=:B1
)
Does anyone know the meaning of the syntax #!
I have never seen something like it before in Oracle
Thanks
It's a query that has originated on a remote database. The database where you've seen this query in V$SQL has been referenced in the query on the remote database using the #DB_NAME syntax
The remote database has pushed the query to your database for execution, but to answer the query, your database needs to pull some information back from the remote database. This is where the #! comes in, basically it's a reference back to the database where the query originated from
For example, create a test database link, even to the same database, and run this:
alter system flush shared_pool;
select sysdate from dual#myself;
select sql_text from gv$sql where sql_fulltext like '%#!%';
SQL_TEXT
--------
SELECT SYSDATE#! FROM "DUAL" "A1"
Often # in databases are related to a database link.
E.g. in Oracle I use
create public database link
mylink
connect to
remote_username
identified by
mypassword
using 'tns_service_name';
if the after this user (remote_username) has a table ANOTHERTABLE you could use:
SELECT "A2"."ANOTHERCOLUMN"
FROM "ANOTHERTABLE"#mylink "A2"
WHERE "A2".ROWID=1
How the ! sign is used here is unclear for me. Normally the ! sign is something you use to access the shell where your database client is running.
I don't know is this helped you. Good luck.

How to determine if database exists on linked server?

I know you can do something like:
select count(*) as Qty from sys.databases where name like '%mydatabase%'
but how could you do something like:
select count(*) as Qty from linkedServer.sys.databases where name like '%mydatabases%'
I guess I could put a stored procedure on the linked server and execute the first select, but is there a way to query a linked server for what databases it holds?
Assuming your linked server login has read permissions on the master.sys.databases table, you can use the following:
select * from linkedserver.master.sys.databases
In the past, I've used this very query on SQL Server 2008 R2.
I think its just a matter of your syntax that is stopping you, try using single quotes instead of %% around your database name:
SELECT COUNT(*) as Qty FROM LinkedServer.master.sys.databases where name like 'mydatabase'
The correct formatting for selecting a Linked Server has already been answered here:
SQL Server Linked Server Example Query
Listed below is a link to a cursor that works:
http://jasonbrimhall.info/2012/03/05/are-my-linked-servers-being-used/
The query will need some rework to include all functions and triggers though.
I'm not sure if a remote master DB is always available through a linked server.
I'll be using the following TRY CATCH probe
BEGIN TRY
EXEC ('SELECT TOP 1 1 FROM MyLinkedServer.MyTestDb.INFORMATION_SCHEMA.TABLES')
END TRY
BEGIN CATCH
PRINT 'No MyTestDB on MyLinkedServer'
END CATCH

SQL - How to insert results of Stored_Proc into a new table without specifying columns of new table?

Using SQL Server 2005, I'd like to run a stored procedure and insert all of the results into a new table.
I'd like the new table to have its columns automatically configured based upon the data returned by the stored procedure.
I am familiar with using the SELECT ... INTO syntax:
SELECT * INTO newtable FROM oldtable
Is this possible?
Edit for clarification: I'm hoping to accomplish something like:
Select * INTO newtable FROM exec My_SP
The only way to do this is w/ OPENROWSET against the local server:
SELECT * INTO #temp
FROM OPENROWSET (
'SQLOLEDB'
, 'Server=(local);TRUSTED_CONNECTION=YES;'
, 'SET FMTONLY OFF EXEC database.schema.procname'
) a
But this is kind of a last-ditch-gotta-do-it-damn-the-consequences kind of method. It requires elevated permissions, won't work for all procedures, and is generally inefficient.
More info and some alternatives here: http://www.sommarskog.se/share_data.html
This seems like a horrible design. You're really going to create a new table to store the results of a stored procedure, every time the stored procedure is called? And you really can't create the table in advance because you have absolutely no idea what kind of output the stored procedure has? What if the stored procedure returns multiple resultsets? What if it has side effects?
Okay, well, if that's what you really want to do...
One way to accomplish this is to use your local server as a linked server and utilize OPENQUERY. First you need to make sure your local server is configured for data access:
EXEC sp_serveroption 'local server name', 'DATA ACCESS', true;
Then you can do something like this:
SELECT * INTO dbo.newtable
FROM OPENQUERY('local server name', 'EXEC yourdb.dbo.yourproc;');
PS How are you going to write code that is going to perform SELECT INTO into a new table name every time (because you can only do SELECT INTO once)? Dynamic SQL? What happens if two users run this code at the same time? Does one of them win, and the other one just gets an error message?
A variation of the same is
create table somename
select * from wherever;