Get SQL Server Job Status - sql

I'm trying to get the status of my jobs in MS SQL Server, the aim is to create an alert in our remote monitoring software if any of the enabled jobs have errored.
Currently I'm using the sys.xp_sqlagent_enum_jobs stored procedure however that seems to show both enabled and disabled jobs, so I tried using the msdb.dbo.sp_help_job, this is exactly what I need but without using the OPENQUERY parameter (which is disabled on the servers) I can't query or capture the results because of the nesting error, I got the same with sp_get_composite_job_info.
So I'm starting to run out of ideas does anyone know of a way to capture this information for query or to store in a able for query later.
I'll include my current code in case it is useful for anyone, it works well returning the number of failed jobs, but if you have a failed job that is disabled this also shows up.
objRecordSet.Open _
"SET NOCOUNT ON " & _
"DECLARE #MaxLength INT " & _
"SET #MaxLength = 50 " & _
"DECLARE #xp_results TABLE ( job_id uniqueidentifier NOT NULL, " & _
"last_run_date nvarchar (20) NOT NULL, " & _
"last_run_time nvarchar (20) NOT NULL, " & _
"next_run_date nvarchar (20) NOT NULL, " & _
"next_run_time nvarchar (20) NOT NULL, " & _
"next_run_schedule_id INT NOT NULL, " & _
"requested_to_run INT NOT NULL, " & _
"request_source INT NOT NULL, " & _
"request_source_id sysname " & _
"COLLATE database_default NULL, " & _
"running INT NOT NULL, " & _
"current_step INT NOT NULL, " & _
"current_retry_attempt INT NOT NULL, " & _
"job_state INT NOT NULL " & _
")" & _
"DECLARE #job_owner sysname " & _
"DECLARE #is_sysadmin INT " & _
"SET #is_sysadmin = isnull (is_srvrolemember ('sysadmin'), 0) " & _
"SET #job_owner = suser_sname () " & _
"INSERT INTO #xp_results EXECUTE sys.xp_sqlagent_enum_jobs #is_sysadmin, #job_owner " & _
"UPDATE #xp_results SET last_run_time = right ('000000' + last_run_time, 6), next_run_time = right ('000000' + next_run_time, 6) " & _
"SELECT count(*) as cnt FROM #xp_results x LEFT JOIN msdb.dbo.sysjobs j ON x.job_id = j.job_id LEFT OUTER JOIN msdb.dbo.syscategories c " & _
"ON j.category_id = c.category_id LEFT OUTER JOIN msdb.dbo.sysjobhistory h ON x.job_id = h.job_id " & _
"AND x.last_run_date = h.run_date AND x.last_run_time = h.run_time AND h.step_id = 0 where h.run_status = 0 ", _
objConnection, adOpenStatic, adLockOptimistic
message = message & "JOBCHECK#" & objRecordSet("cnt") & vbNewLine

Not that hard. Keep in mind SQL Server keeps meta data info at all times on what detail is being done to the server actively. I would do this to find failures in that you could create a proc or function, call it by date range. I gave an example of just the query though for the time being:
use msdb;
declare
#Start int = cast( convert(varchar,
dateadd(ww, datediff(ww, 0, getdate())-1,0) -- last week starting
, 112) as int)
, #End int = cast( convert(varchar,
getdate() -- current datetime
, 112) as int)
;
Select
j.name
, j.description
, cast( cast(jh.run_date as varchar) + ' ' + left(jh.run_time, 2) + ':' + substring( cast(jh.run_time as varchar), 3, 2) as datetime) as TimeRan
, jh.message
, jh.step_id
, jh.step_name
from sysjobs j (nolock)
join sysjobhistory jh (nolock) on j.job_id = jh.job_id
and jh.run_date between #Start and #End
and jh.run_status = 0 -- 0 is failure

Many thanks using help from djangojazz, I was able to do what I wanted:
use msdb;
Select count(*) as cnt
from sysjobs j (nolock)
join sysjobhistory jh (nolock) on j.job_id = jh.job_id
and instance_id = (
select MAX(instance_id)
from sysjobhistory (nolock)
where job_id = j.job_id
)
and j.enabled = 1
and jh.run_status = 0

Related

Unclosed quotation mark after the character string ')'

I have a stored procedure SP_CHADOTHERREPORTS
When executing SP_CHADOTHERREPORTS from VB.NET. I get an error like this:
here is my code for executing SP_CHADOTHERREPORTS in VB.NET:
Dim subreporttype as varchar = "Report1"
Dim DatabaseFINAL as varchar = "TBLREPORT"
Dim acctcode as varchar = "TBLREPORT.acctcode"
Dim varmonth as integer = 1
Dim varyear as integer = 2011
Execute("EXECUTE SP_CHADOTHERREPORTS '" & subreporttype & "','" & DatabaseFINAL & "','" & acctcode & "'," & dt.Rows(ctr).Item("ReporttypeName").ToString & "," & varmonth & ", " & varyear & "")
While this one is the code in SP_CHADOTHERREPORTS from SQL SERVER 2008:
ALTER PROCEDURE [dbo].[SP_CHADOTHERREPORTS]
#Subreport as varchar(100),
#TableName as varchar(100),
#AccountCode as varchar(100),
#ReportName as varchar(100),
#AcctPeriod as numeric(18,0),
#AcctYear as numeric(18,0)
AS
IF #Subreport = 'REPORT1'
BEGIN
DECLARE #Query as varchar(1000)
SET #Query =
'UPDATE CHADotherCharges ' +
' SET Jan = ( ' +
' SELECT Jan FROM '+ #TableName +
' WHERE CHADothercharges.acctcode = '''+ #AccountCode +'' +
' AND ReportName = '+ #ReportName +
' AND acctperiod = '+ convert(varchar(18), #AcctPeriod) +
' AND acctyear = '+ convert(varchar(18), #AcctYear) +
') ' +
'FROM Chadothercharges WHERE type IN(''+'',''SUM'',''-'')'
EXEC (#Query)
END
One obvious problem is this line:
' WHERE CHADothercharges.acctcode = '''+ #AccountCode +'' +
-------------------------------------------------------^
That does nothing. I assume you want to put in a single quote, as ''''.
However, the real way to approach this is by using sp_executesql and using parameters for all the constant values in the query. You can't use this for #TableName, but you can use it for the values in the WHERE.

using Transaction query in jsp page

I use below query in my jsp page. but I'm not sure Is it true to use this query in jsp page.
int i = st.executeUpdate("'BEGIN TRANSACTION DECLARE #id [int] SELECT #id = SCOPE_IDENTITY() INSERT INTO Viewer(Reserve_ID, F_Name, L_Name, Competition_ID, City, Phone, [E-mail]) VALUES (#id, '" + fname + "','" + lname + "','" + 30 + "','" + city + "','" + phone + "','" + email + "' ) INSERT INTO Reservation_Inf(Reservation_Date, Competition_ID, NumberOfTicket, Position_ID) VALUES ('" + dNow + "','" + 30 + "','" + 1 + "','" + 8 + "' ) COMMIT TRANSACTION '" );
if (i > 0) {
response.sendRedirect("Success.jsp");
} else {
response.sendRedirect("Fail.jsp");
}
It gives this error :
Incorrect syntax near 'BEGIN TRANSACTION DECLARE #id [int] SELECT #id = SCOPE_IDENTITY() INSERT INTO Viewer(Reserve_ID, F_Name, L_Name, Competition_ID,'.

Can these two SQL statements be made into one? Changing multiple indices with two constraints

I have a form that users can use to edit data in my database. The database is structured like this:
If a user wants to edit both a FAVE_COLOR and a FAVE_FOOD, how would I go about doing that in my SQL statement? I can think of this, but is there a way to do this in one statement?
string sql1 = "UPDATE MYTABLE " +
"SET PROP_VALUE = '" + form["color"] + "' " +
"WHERE ID = " + form["id"] + " " +
"AND PROP_NAME = 'FAVE_COLOR'"
string sql2 = "UPDATE MYTABLE " +
"SET PROP_VALUE = '" + form["food"] + "' " +
"WHERE ID = " + form["id"] + " " +
"AND PROP_NAME = 'FAVE_FOOD'"
string sql = "UPDATE MYTABLE " +
"SET PROP_VALUE = CASE " +
"WHEN PROP_NAME = 'FAVE_COLOR' THEN '" + form["color"] + "' " +
"WHEN PROP_NAME = 'FAVE_FOOD' THEN '" + form["food"] + "' " +
"END " +
"WHERE ID = " + form["id"] + " " +
"AND PROP_NAME IN ('FAVE_COLOR', 'FAVE_FOOD')"
But beware of SQL injection! You really should be using prepared statements, into which you pass your variables as parameters that do not get evaluated for SQL. If you don't know what I'm talking about, or how to fix it, read the story of Bobby Tables.
You can use case statements:
UPDATE MYTABLE
SET PROP_VALUE = (
CASE favefood
WHEN PROP_NAME = 'FAVE_FOOD'
THEN 'PIZZA'
CASE favecolor
WHEN PROP_NAME = 'FAVE_COLOR'
THEN 'BLUE'
WHERE ID = #myIdValue
For MS SQL Server you can use an UPDATE FROM which will update two properties at the same time, like this:
CREATE TABLE MYTABLE (
ID INT,
PROP_NAME VARCHAR(20),
PROP_VALUE VARCHAR(20));
go
INSERT INTO MYTABLE VALUES (1, 'A','B')
go
INSERT INTO MYTABLE VALUES (1, 'C', 'D')
go
UPDATE MYTABLE
SET PROP_VALUE = X.PROP_VALUE
FROM MYTABLE MT JOIN (
SELECT 'A' AS PROP_NAME, 'F' AS PROP_VALUE
UNION
SELECT 'C' AS PROP_NAME, 'G' AS PROP_VALUE) AS X ON MT.PROP_NAME = X.PROP_NAME
WHERE ID = 1
For other SQL DB server the solution should be similar if not identical.

Executing SQL powershell query in VBscript

I am executing sql query in vbscript, query is as follow it gives information about drives available for each server
VBScript code (slightly restructured):
Strquery = "DECLARE #Totaldbspacegb BIGINT;" & _
"DECLARE #Totaldriveusedspacegb INT;" & _
"DECLARE #Totaldrivefreespacegb INT;" & _
"DECLARE #Svrname VARCHAR(255);" & _
"DECLARE #Sql VARCHAR(400);" & _
"DECLARE #Forcast6monthsgb NUMERIC(38, 6);" & _
"DECLARE #Forcast12monthsgb NUMERIC(38, 6);"
Strquery = Strquery & "; DECLARE #Avggrowthingb NUMERIC(38, 6);" & _
"CREATE TABLE #Temp1(Yer INT NULL, Mnth INT NULL," & _
"Sumdbinmb NUMERIC(38, 6)NULL, Id INT IDENTITY(1, 1) NOT NULL);" & _
"CREATE TABLE #Temp4(Totaldriveusedspacegb INT, Totaldrivefreespacegb INT);"
Strquery = Strquery & "; SELECT #Totaldbspacegb = SUM(Size) FROM Sys.Master_Files"
Strquery = Strquery & "; SELECT #Totaldbspacegb = #Totaldbspacegb * 8. / 1024.0 / 1024"
Strquery = Strquery & "; SET #Svrname = '" & Strserver & "';"
Sql = " Powershell.Exe - C ""Get-WmiObject -Class Win32_Volume -Filter ''DriveType = 3''| select name,label,capacity,freespace | foreach{$_.name+''!''+$_.label+''|''+$_.capacity/1048576+''%''+$_.freespace/1048576+''*''}"""
Strquery = Strquery & "CREATE TABLE #Output(Line VARCHAR(255)); INSERT INTO #Output"
Strquery = Strquery & "; EXEC Xp_Cmdshell '" & sql & "';"
Strquery = Strquery & "; SELECT * FROM #Output;"
Resulting (formatted) SQL code:
DECLARE #Totaldbspacegb BIGINT;
DECLARE #Totaldriveusedspacegb INT;
DECLARE #Totaldrivefreespacegb INT;
DECLARE #Svrname VARCHAR(255);
DECLARE #Sql VARCHAR(400);
DECLARE #Forcast6monthsgb NUMERIC(38, 6);
DECLARE #Forcast12monthsgb NUMERIC(38, 6);
;
DECLARE #Avggrowthingb NUMERIC(38, 6);
CREATE TABLE #Temp1(Yer INT NULL,
Mnth INT NULL,
Sumdbinmb NUMERIC(38, 6)NULL,
Id INT IDENTITY(1, 1) NOT NULL
);
CREATE TABLE #Temp4(Totaldriveusedspacegb INT,
Totaldrivefreespacegb INT
);
;
SELECT #Totaldbspacegb = SUM(Size)
FROM Sys.Master_Files;
SELECT #Totaldbspacegb = #Totaldbspacegb * 8. / 1024.0 / 1024;
SET #Svrname = '...';
CREATE TABLE #Output(Line VARCHAR(255));
INSERT INTO #Output;
EXEC Xp_Cmdshell 'Powershell.Exe - C "Get-WmiObject -Class Win32_Volume -Filter ''DriveType = 3''| select name,label,capacity,freespace | foreach{$_.name+''!''+$_.label+''|''+$_.capacity/1048576+''%''+$_.freespace/1048576+''*''}"';
;
SELECT *
FROM #Output;
I am executing this query it gave me output while running from management studio while running in .vbs file it give me record count as null, how to find whether query is executing sucessfully.
is it due to powershell command it is not running in vbscript.
Please help
Do you want to update the temporary table #Output with the result of the PowerShell command? If so, I don't think your instructions will do what you want.
INSERT INTO #Output;
EXEC Xp_Cmdshell 'Powershell.Exe -C "..."';
SELECT *
FROM #Output;
INSERT INTO #Output; is not a valid statement, and you don't do anything with the output of the PowerShell command.

SQL UPDATE doesn't work with foreign languages (Arabic)

the UPDATE gives ???? if the updater field was written in Arabic and this is my query:
UPDATE students
SET first_name = 'الاسم' , last_name = 'الاسم الاخير' ,
father_name = 'الاسم الاخير' , mother_name = '',
birth_date = '1/1/1990 12:00:00 AM' , education_level = '' ,
address = '' , notes = ''
WHERE student_id = 33
And here is the result of the update:
student_id first_name last_name mother_name father_name birth_date
33 ????? ????? ?????? ??????????? 1990-01-01
//the answer is great and thank you people, another question is that I am using this UPDATE syntax in my C# program
command.CommandText = "UPDATE students SET " +
"first_name = " + "'" + first_name + "'" + " , last_name = " + "'" + last_name + "'" +
" , father_name = " + "'" + father_name + "'" + " , mother_name = " +
"'" + mother_name + "'" + ", birth_date = " + "'" + birth_date + "'" +
" , education_level = " + "'" + education_level + "'" +
" , address = " + "'" + address + "'" + " , notes = " + "'" + notes + "'" +
" WHERE student_id = " + id ;
//how to use the character N
You have forgotten the N prefix before your string literals which is required so they will be treated as nvarchar rather than varchar
SET first_name = N'الاسم' etc.
without that the text is coerced into whatever characters the code page of your default collation can deal with.
Create the database with this collation Arabic_CI_AS, you won't need to put N before the Arabic characters.