I am trying to delete a datapase in azure portal. After removing from SQL pool, I am getting the following error:
Msg 37106, Level 16, State 1, Line 7 The database '{databasename}' on server {'servername}' is in use by job account 'jobagent'. The database cannot be deleted or renamed while associated with a job account.
How should I address fixing this?
If you don't have other databases on it, you could simply drop the server and recreate it. That will get you around the issue.
Else Follow below steps delete database
You can kill a process by a right click on the process in the grid and selecting the Kill Process menu item. You will be asked for a confirmation to kill the related process and then will kill the open connection to the database over this process. This action is just like running to kill sql process t-sql command for a single process.
Way to drop all active connections of a database can be implemented by generating dynamic sql commands that runs a list of "Kill #spId" commands.
DECLARE #DatabaseName nvarchar(50)
SET #DatabaseName = N'Works'
--SET #DatabaseName = DB_NAME()
DECLARE #SQL varchar(max)
SET #SQL = ''
SELECT #SQL = #SQL + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(#DatabaseName) AND SPId <> ##SPId
-- SELECT #SQL
EXEC(#SQL)
A very similar to the sql code above, an other code block can be used by using the COALESCE as shown below
DECLARE #DatabaseName nvarchar(50)
SET #DatabaseName = N'Works'
DECLARE #SQL varchar(max)
SELECT #SQL = COALESCE(#SQL,'') + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(#DatabaseName) AND SPId <> ##SPId
--SELECT #SQL
EXEC(#SQL)
You can also refer this article
I have below EmployeeData table and due to some known reasons BAD data is getting inserted and i am working on code fix, but meanwhile i want to check for bad data until the fix is deployed. If you observe John has 1 for both Active and IsEmpTermed columns.
Currently i am running the below query to check for Bad data manually in SQL Server. I want to automate this task and send an email to me if it finds bad data i.e. Active =1 and IsEmpTermed =1. What and How to do it?
select * from EmployeeData Where Active=1 and IsEmpTermed = 1;
Thanks in advance.
Quick way would be use the #query argument with sp_send_dbmail and put that code in a SQL Server Agent Job.
Here's a simple example of what that sp_send_dbmail looks like:
EXEC msdb.dbo.sp_send_dbmail
#profile_name = '' --This is specific to your setup
,#recipients = 'your#email.com'
,#subject = 'This is the subject'
,#query = 'select EmpID, FirstName, LastName from EmployeeData Where Active=1 and IsEmpTermed = 1' --The query
,#execute_query_database = '' --The name of your database goes here where the query should be executed
That will basically execute the query you specified in #query, dump the results into an email and send it to whomever is in #recipients
If you don't know what the #profile_name is for your server configuration you can run
EXEC msdb.dbo.sysmail_help_profileaccount_sp;
That will return a list of the mail profiles configured on your server. You will use the value from the "profile_name" column. If there are multiples, this is something I can't tell you as it is specific to your server configuration.
Once you have all that defined and working by manually running it in SSMS, go create a SQL Server Agent Job with a T-SQL step and add the "EXEC msdb.dbo.sp_send_dbmail" code. Defined a schedule at whatever frequency you would like it to run.
A lot of times I'll code it to check if the data issue exists before sending an email, so it will only send an email when the data issue exists so it won't keep spamming me if there are no issues, something like this
--The IF EXISTS checks if the data issue exists before sending an email
IF EXISTS(SELECT TOP 1 'x' FROM dbname.dbo.EmployeeData Where Active=1 and IsEmpTermed = 1)
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#profile_name = '' --This is specifc to your setup
,#recipients = 'your#email.com'
,#subject = 'This is the subject'
,#query = 'select EmpID, FirstName, LastName from EmployeeData Where Active=1 and IsEmpTermed = 1' --The query
,#execute_query_database = '' --The name of your database goes here
END
I'm trying to use sp_send_dbmail to send the results of a query through a SQLAgent job in SQL Server 2014. I believe I have my DBMail profile set up properly but when running this:
exec msdb.dbo.sp_send_dbmail
#profile = 'TestProfile',
#recipients = 'testmail#gmail.com',
#subject = 'Test',
#query = 'SELECT id FROM TestTable',
#attach_query_result_as_file = 1,
#query_attachment_filename = 'TestValues.txt'
I get the following error message:
Failed to initialize sqlcmd library with error number -2147467259.
Googling this error message didn't turn up anything useful, likely due to the generic error number. Anyone have some insight into this error message?
I found that despite both my query window (for testing) and SqlAgent job were pointing at my desired DB, sp_send_dbmail doesn't seem to have any database context. My original post was failing because SQL didn't know where to run SELECT * FROM TestTable. The fix is to provide sp_send_dbmail with database context by either fully qualifying your table in the #query parameter:
#query = 'SELECT id FROM testDB.dbo.TestTable'
or by providing the optional #execute_query_database parameter:
#execute_query_database = 'testDB'
Enable sysadmin server role for the account that is used to run the SQL Server Agent.Below are the screenshots.
Error
Fix
Now the SQL Server Job runs without any errors and I get an email from dbmail.
There's another reason why you might get this error; if the query has an issue.
In our case we had (note that it's not due to a syntax error; note the missing quotes):
DECLARE #EmailQuery varchar(max) = 'select
e.Field1,
REPLACE(REPLACE(e.ExceptionReason, CHAR(13), ''), CHAR(10), '') ExceptionReason,
e.UserName
from dbo.tblException e'
Once we corrected it as follows, it worked fine:
DECLARE #EmailQuery varchar(max) = 'select
e.Field1,
REPLACE(REPLACE(e.ExceptionReason, CHAR(13), ''''), CHAR(10), '''') ExceptionReason,
e.UserName
from dbo.tblException e'
I'm looking to query all databases mapped to a user, similar to Security > Logins > Properties > User Mapping.
This may be done in SQL 2005 if possible
For example, something similar to:
SELECT name
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1
But perform the query from an administrative user, as opposed to running the above query as the user itself.
How would something like this be performed?
Thank you.
Well this might be a start, probably not the nice output you'd hope for (and it produces two resultsets):
EXEC sp_helplogins N'floob';
But it does work on SQL Server 2000. If you want to try and replicate some of the functionality in the procedure, you can see how it's checking for permissions, basically a cursor through every database. On SQL Server 2000:
EXEC sp_helptext N'sp_helplogins';
On 2005+ I much prefer the output of OBJECT_DEFINITION():
SELECT OBJECT_DEFINITION(OBJECT_ID(N'sys.sp_helplogins'));
So you could write your own cursor based on similar logic, and make the output prettier...
Here is a quick (and not complete) example, doesn't cover much but an idea to get started if the above is not sufficient:
DECLARE #login NVARCHAR(255);
SET #login = N'foobarblat';
-- above would be an input parameter to a procedure, I presume
CREATE TABLE #dbs(name SYSNAME);
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + N'INSERT #dbs SELECT ''' + name + ''' FROM '
+ QUOTENAME(name) + '.sys.database_principals AS u
INNER JOIN sys.server_principals AS l
ON u.sid = l.sid
WHERE l.name = #login;'
FROM sys.databases
WHERE state_desc = 'ONLINE'
AND user_access_desc = 'MULTI_USER';
EXEC sp_executesql #sql, N'#login SYSNAME', #login;
SELECT name FROM #dbs;
DROP TABLE #dbs;
As I said, this is not complete. Won't know if the user has been denied connect, is member of deny reader/writer roles, won't show the alias if the user name in the db doesn't match the login, etc. You can dig into more details from sp_helplogins depending on what you want to show.
The EXECUTE AS functionality was added in the 2005 release, so I don't think you can run that in 2000. You could probably mimick it by putting the relevant code in a job and setting the job owner to an admin user, but it would process with the job not inline.
I would like to set up a SQL Server 2008 Alert to notify me when any procedure executes for 1 second or longer (just an example).
Any ideas?
EDIT:
Okay, it seems this is not possible. But, just to nudge you in another direction, I know that there are statistics tables in the master database which hold compilation counts, number of calls and other various statistics. Could I maybe periodically query them and then report on it, somehow?
no there are no notifications for this.
you'll have to set up a trace and poll it every now and then.
I'd like to add to Mladen Prajdic's correct answer and to improve upon kevchadders' answer from SQL Server Central. The solution I propose below uses DBMail instead of SQLMail (which is used by SQLServerCentral's solution by way of the xp_sendmail call). Essentially, SQLMail uses MAPI and is harder to setup and DBMail uses SMTP and is easier to setup. Here's more information about the difference between the two.
I could not get SQL Server Central's solution to work in SQL 2005 and the solution below has only been tested on my installation of SQL 2005 - YMMV based on version.
First, you'll need a new UDF, which will translate the job id into the process id for a JOIN:
CREATE FUNCTION dbo.udf_SysJobs_GetProcessid(#job_id uniqueidentifier)
RETURNS VARCHAR(8)
AS
BEGIN
RETURN (substring(left(#job_id,8),7,2) +
substring(left(#job_id,8),5,2) +
substring(left(#job_id,8),3,2) +
substring(left(#job_id,8),1,2))
END
And then the sproc:
CREATE PROC sp_check_job_running
#job_name char(50),
#minutes_allowed int,
#person_to_notify varchar(50)
AS
DECLARE #minutes_running int,
#message_text varchar(255)
SELECT #minutes_running = isnull(DATEDIFF(mi, p.last_batch, getdate()), 0)
FROM master..sysprocesses p
JOIN msdb..sysjobs j ON dbo.udf_sysjobs_getprocessid(j.job_id) = substring(p.program_name,32,8)
WHERE j.name = #job_name
IF #minutes_running > #minutes_allowed
BEGIN
SELECT #message_text = ('Job ' + UPPER(SUBSTRING(#job_name,1,LEN(#job_name))) + ' has been running for ' + SUBSTRING(CAST(#minutes_running AS char(5)),1,LEN(CAST(#minutes_running AS char(5)))) + ' minutes, which is over the allowed run time of ' + SUBSTRING(CAST(#minutes_allowed AS char(5)),1,LEN(CAST(#minutes_allowed AS char(5)))) + ' minutes.')
EXEC msdb.dbo.sp_send_dbmail
#recipients = #person_to_notify,
#body = #message_text,
#subject = 'Long-Running Job to Check'
END
This sproc can be easily scheduled as a SQL Server Agent job or any other method necessary. It takes no action if the job is not running or it is running within specified parameters. It sends the email if the job has run longer than specified.
e.g.
EXEC sp_check_job_running 'JobNameGoesHere', 5, 'admin#mycompany.com'
HT: http://www.sqlserverspecialists.co.uk/blog/_archives/2008/11/26/3996346.html
If found this on sqlservercentral (it probably for an older version of SQL Server, but still might be relevant to 2008)
Alert Procedure for Long-Running Job
http://www.sqlservercentral.com/scripts/Lock+and+Connection+Management/30144/
Text below if you cant access it.
For jobs that run periodically and should take only a short time to run, a DBA may want to know when the job has been running for an excessive time. In this case, just checking to see IF the job is running won't do; the ability to make sure that it hasn't been running for a long period is needed. Matching the job id to a process id in sysprocesses requires some re-arranging of the job id to do the match. This script creates a stored procedure that will accept a job name, maximum run time allowed, and email address to notify. It will then use the job name to re-string the job number and check sysprocesses (based on the process id being part of the program name) to determine the amount of time the job has been runing, then alert if that time is over the "time allowed" parameter.
CREATE proc sp_check_job_running
#job_name char(50),
#minutes_allowed int,
#person_to_notify varchar(50)
AS
DECLARE #var1 char(1),
#process_id char(8),
#job_id_char char(8),
#minutes_running int,
#message_text varchar(255)
select #job_id_char = substring(CAST(job_id AS char(50)),1,8)
from msdb..sysjobs
where name = #job_name
select #process_id = substring(#job_id_char,7,2) +
substring(#job_id_char,5,2) +
substring(#job_id_char,3,2) +
substring(#job_id_char,1,2)
select #minutes_running = DATEDIFF(minute,last_batch, getdate())
from master..sysprocesses
where program_name LIKE ('%0x' + #process_id +'%')
if #minutes_running > #minutes_allowed
BEGIN
select #message_text = ('Job '
+ UPPER(SUBSTRING(#job_name,1,LEN(#job_name)))
+ ' has been running for '
+ SUBSTRING(CAST(#minutes_running AS char(5)),1,LEN(CAST(#minutes_running AS char(5))))
+ ' minutes, which is over the allowed run time of '
+ SUBSTRING(CAST(#minutes_allowed AS char(5)),1,LEN(CAST(#minutes_allowed AS char(5))))
+ ' minutes.')
EXEC master..xp_sendmail
#recipients = #person_to_notify,
#message = #message_text,
#subject = 'Long-Running Job to Check'
END
-- Typical job step syntax for job to do the checking
execute sp_check_job_running
'JobThatSHouldBeDoneIn5Minutes',
5,
'DBAdmin#mycompany.com'
You could use a monitoring software like Nagios to periodically count the number of slow queries in your database.
I personally use the following query with the excellent PRTG. I set it to send me an email each time I have more than 5 queries with an execution time greater than 3 seconds each, or when the slowest query takes longer than 10 seconds:
SELECT total_elapsed_time / execution_count / 1000000 avg_elapsed_time, execution_count, creation_time, last_execution_time,
SUBSTRING(st.text, (qs.statement_start_offset/2) + 1, ((CASE statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE total_elapsed_time / execution_count / 1000000 >= 3 -- filter queries that takes > 3 seconds
AND CHARINDEX('dm_exec_query_stats', st.text) = 0 -- In case this query is slow, we don't want it in the result set!
ORDER BY total_elapsed_time / execution_count DESC;
Disclaimer: this query is based on https://stackoverflow.com/a/820252/638040
Now if you want to monitor your Stored Procedures, then just use sys.dm_exec_procedure_stats instead of sys.dm_exec_sql_text (also remove the field creation_time from the selection and tweak the SUBSTRING on st.text)
You can log slow running queries use SQL Profiler, but that won't help you with an alert, specifically. (I suppose you could log to a File or to a database table, and have something else "listen" and raise an alert).
In case you are not familiar with SQL Profiler here are the steps:
You should run SQL Profiler on something other than the server itself.
Start with the SQLProfilerTSQL_Duration template
Set the Filter : Duration : "Greater than" to 1000 (milliseonds)
In the filters you can restrict the Database, Login, or similar if necessary.
In the Events you can restrict to just SProcs (default also includes SQL statements)
If you are not looking for a free solution, you could take a look at SQL Sentry. It does what you ask for and more.