Exclamation mark in SQL (Oracle) - 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.

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

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.

New to SQL developer - get "invalid SQL statement" whatever I try to do (ORA:00900)

I have a view set up where I'm supposed to be able to access the tables, but any query I try to write throws the same error message. Does anyone know what could be wrong, or can someone suggest some next steps for troubleshooting? Is there something I may need to do prior to querying these tables?
You can't run a MySQL command like SHOW TABLES in Oracle.
SHOW is a SQL*Plus command. It lets you see what your session settings are.
SHOW ALL or SHOW PAGESIZE
You could create a SQL Code Template called SHOW or SHOWTABLE that you can activate to write the SQL for you, e.g.
select table_name from user_tables order by 1;

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