Query to get active processes in Oracle - sql

I am trying to see what queries are currently running in an oracle DB. However, when I try using the table v$session it gives me an error:
What's the cause of this and what would be the correct way to get the active processes that are running?
I'm looking to get the necessary information to be able to cancel a query for a given user. Let me give an example:
1) User executes query in the application. We add in a comment so we can 'track' that query:
/* Query-ID-1283849 */ select * from mytable
2) Now, if the user clicks the "Cancel" button while the query is running (let's say the query is taking a very long time to respond), we allow the user to cancel that query, given that the user will probably NOT be a sys user but a 'normal' user with read-only privileges.
How could this be done?

At the fundamental database level, you can't kill individual queries. You kill individual sessions. I'm inferring from your question that your specific use case is inside an application, not a tool like Sql Developer or Sql Plus.
Session killing can be done by users that have special database privileges to kill sessions. If you are inside an application running multiple queries in one session, killing the session will effectively kill your application and require either a) an application restart or b) gracefully programatically handling the dropped session.
If you are using an n-tier ORM framework that handles database interactions for you, you may be in a position where killing the session won't have any affect on your application other than the currently running statement.
Another way in your app to handle isolating sessions and queries is to run a multi-threaded application. Each query spawns a new thread, and the thread can be killed without necessarily killing the session.
Basically, the short answer is you can kill a query only by killing its session. Your approach of looking at v$session is correct and necessary to find the session id for any givel sql statement, you just need to have your DBA grant your privileges to the v$session and v$sql synonyms.
Update specific to Sql Developer, based on OP's comment for clarification:
Sql Developer has an option to allow running parallel queries, taking advantage of threads and multiple connections. That setting is found at Tools > Preferences > Database > Worksheet. Regardless of the setting, when you click the query cancel button, the app is still sending a session kill request. The GUI will usually gracefully start a new session and the end user is none the wiser about it. But sometimes things don't work out and the GUI freezes or you end up with no connection and have to manually reconnect.
To add to the complexity, the behavior depends on the driver/client used by your application. OCI, thick clients, and thin clients have shown different behaviors in the past when it comes to kill requests. In fact, in Sql Developer, you have an option to force it to use OCI or a thick driver so that you can avoid certain behaviors.
I'd highly recommend getting rights to view v$session and play around with this. It's fun to learn more about how Oracle manages sessions.
I just discovered that the latest version, Oracle 18c, allows killing an individual query within a session. I'm on 12c so I have not tried this. https://docs.oracle.com/en/database/oracle/oracle-database/18/admin/managing-processes.html#GUID-7D8E5E00-515D-4338-8B86-C2044F6D2957
Relevant parts from the documentation.
5.10.5 Cancelling a SQL Statement in a Session You can cancel a SQL statement in a session using the ALTER SYSTEM CANCEL SQL statement.
Instead of terminating a session, you can cancel a high-load SQL
statement in a session. When you cancel a DML statement, the statement
is rolled back.
The following clauses are required in an ALTER SYSTEM CANCEL SQL
statement:
SID – Session ID
SERIAL – Session serial number
The following clauses are optional in an ALTER SYSTEM CANCEL SQL
statement:
INST_ID – Instance ID
SQL_ID – SQL ID of the SQL statement
You can view this information for a session by querying the GV$SESSION
view.
The following is the syntax for cancelling a SQL statement:
ALTER SYSTEM CANCEL SQL 'SID, SERIAL, #INST_ID, SQL_ID';

Related

How to regularly update or create a SQL Server table?

I need to collect data from a SQL Server table, format it, and then put it into a different table.
I have access to SQL Server but cannot setup triggers or scheduled jobs.
I can create tables, stored procedures, views and functions.
What can I setup that will automatically collect the data and insert it into a SQL Server table for me?
I would probably create a stored procedure to do this task.
In the stored procedure you can create a CTE or use temp tables (depending on the task) and do all the data manipulation you require and once done, you can use the SELECT INTO statement to move all the data from the temp table into the SQL Server table you need.
https://www.w3schools.com/sql/sql_select_into.asp
You can then schedule this stored procedure to run at a time desired by you
A database is just a storage container. It doesn't "do" things automatically all by itself. Even if you did have the access to create triggers, something would have to happen to the table to cause the trigger to fire, typically a CRUD operation on the parent table. And something external needs to happen to initiate that CRUD operation.
When you start talking about automating a process, you're talking about the function of a scheduler program. SQL Server has one built in, the SQL Agent, and depending on your needs you may find that it's appropriate to enlist help from whoever in your organization does have access to it. I've worked in a couple of organizations, though, that only used the SQL Agent to schedule maintenance jobs, while data manipulation jobs were scheduled through an outside resource. The most common one I've run across is Control-M, but there are other players in that market. I even ran across one homemade scheduler protocol that was just built in C#.NET that worked great.
Based on the limitations you lay out in your question, and the comments you've made in response to others, it sounds to me like you need to do socialize your challenge within your organization to find out what their routine mechanism is for setting up data transfers. It's unlikely that this is the first time it's come up, unless the company was founded in the last week or two. It will probably require that you set up your code, probably a stored procedure or maybe an SSIS package, and then work with someone else, perhaps a DBA or a Site Operations team or some such, to get that process automated to fire when you need it to, whether through an Agent job or maybe a file listener.
Well you have two major options, SP and SSIS.
Both of them can be scheduled to run at a given time with a simple Job from the SQL Server Agent. Keep in mind that if you are doing this on a separate server you might need to add the source server as a Linked Server so you can access it from the script.
I've done this approach in the past and it has worked great. Note, for security reasons, I am not able to access the remote server's task scheduler, so I go through the SQL Server Agent:
Run a SQL Server Agent on a schedule of your choice
Use the SQL Server Agent to call an SSIS Package
The SSIS Package then calls an executable which can pull the data you want from your original table, evaluate it, and then insert a formatted version of it, one record at a time. Alternatively, you can simply create a C# script within the SSIS package via a Script Task.
I hope this helps. Please let me know if you need more details.

Is long running select locking updates on sql server

We have a monitoring query for our admins that they run directly in the management studio. This query is a long running query that analyses all records in a table. We have noticed now that when this query is running incoming updates a blocked until this query is finished. After a little investigation we have seen that on sql server select does a shared lock that blocks exclusive locks and that an update does a update lock and then a exclusive lock.
https://www.sqlpassion.at/archive/2014/07/28/why-do-we-need-update-locks-in-sql-server/#comment-104367
https://learn.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms186396(v=sql.105)
Is this a behavior that we can change? What is the best practice to avoid this situation if we have a public portal as frontend where we have many selects also a little bit longer running and different updates on the same table?

Making a connection in Single User Mode

So I have a third party vendor software that I have to call in an SQL Agent Job to restore my databases. So my first step is to set the database in single user mode, my second step is to call the software to start the restore. The problem is, the software takes so long to actually start the restore (its doing it all across the network) that another user can swoop in and take over the database.
Is there a way to put the DB in single user mode and then grab that connection right away? I have tried with a few "Select Getdate()" but I feel that is taking it from the system, and not the database. Do I have to select from a specific table in the database to get it to work?
Thanks
Rather than place the database in single user mode, take the database offline in the context of another database:
USE tempdb;
ALTER DATABASE DatabaseToRestore
SET OFFLINE WITH ROLLBACK IMMEDIATE;
Use the "Client Application Name" option along with the "-m" option that places SQL into single user mode.
That way only an application that matches the name given can connect and take the connection. Obviously you need to ensure that your client process that's doing the restore has a distinct name!
See here for info on the various SQL Server startup options: https://msdn.microsoft.com/en-us/library/ms190737.aspx
Also, I was under the impression you had to be an admin to connect in single user mode, which of course your normal users should not be. Please someone correct me if I'm wrong on that point!

Capture SQL Server connections

Is there any way to capture SQL Server connections for when a user connects to my database until the user disconnects. For example, I want to capture login data for every user that accesses my SQL Server through Excel. Is there a trigger or DMV that will capture the time the user spent connected? I've used sysprocesses in the past and it will show me the connections and from what program, but I need it to be more like a trigger.
Checkout the auditing functions built into sql server.
Maybe you can use this to accomplish your goals (you can capture success and fail login attempts)
ADDED INFO
This webpage above is specifically re: login auditing - introduced in sql 2005
ADDED INFO PART DEUX
Read your question again, and see you want the duration not (not just the login) -- a little harder, but, see the reference for sp_trace_setevent. You should see events for login and logoff here. I've heard that capture logout is a bit more server intensive. Also, not that people do not always logout. They lose connections, crash the machine, etc. not sure how trustworthy the logout data will be. Connection pooling may also complicate you life.

How to monitor and log all the SQL insert commands

I am using Oracle SQL Dev 2.1.1.64
I work with application that uses oracle database for storage.
Is there any way in SQL Dev. to monitor and log all the insert commands that are "coming" from the web application into database? Can you tell me how to do that?
audit insert table by <web-application-user> by access
should get you started.
Be sure to set the parameters audit_trail and audit_file_dest as you need them.
After that, you find the operations either in sys.aud$ or in the directory specified by audit_file_dest.
There is also fine grained auditing into which you might take a look, but from your question, using fine grained auditing (FGA) would seem to be overkill.
You can write a trigger for the tables you want to monitor. If you are only interested on the insert queries coming from the Web Application, you can check on the trigger for some specific username/schema accessing the table, and use that username as your web application credentials.
Alternatively you can also use Oracle's AUDIT feature. It requires a little bit of Oracle Database Administration knowledge to implement though...
You could query v$SQL, but you would need to have the relevant GRANTS to enable you to do this.
For long running sessions you can also monitor progress using v$session_longops
hope this helps you.
Create a trigger that writes to a journaling table whenever a change of data in the table happens (insert, update, delete).
Before delete, after insert, after update triggers are what you want.
It won't specifically log only the web application, but if you log the user making the change you will be able to filter on that when viewing the data.