is there any way to show the status/output of an sql server agent job?
I have an application that runs a stored procedure which actually runs an SQL Server Agent Job (See Below) but is there any way to show the status of that job that is running? If the Job fails I can check by going directly in to SQL Server Studio and viewing the history of the job but there is no way to tell from the application.
Ideally I'd like to be able to display something like this in the application:
Executing job...
Starting Step 1... Success
Starting Step 2... Success
But if any one knows how to even display
Job Ran Successfully or Job Failed. Error Message..
This is my current code that runs the stored procedure
thanks for any help, ideas, suggestions on where to start
Sub btnImport_click(ByVal sender As Object, ByVal e As EventArgs)
Dim sqlConnection1 As New SqlConnection("CONNECTION STRING")
Dim cmd As New SqlCommand
Dim rowsAffected As Integer
cmd.CommandText = "dbo.runImportDGDataJob"
cmd.CommandType = CommandType.StoredProcedure
cmd.Connection = sqlConnection1
sqlConnection1.Open()
rowsAffected = cmd.ExecuteNonQuery()
sqlConnection1.Close()
End Sub
Here is my answer. Default.aspx:
<%# Page Title="Home Page" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="LaunchJobAndWaitTillDone_VB._Default" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<div class="jumbotron">
<h1>Launch Job And Wait Till Done (VB)</h1>
<p class="lead">Launch SQL Server Agent Job, wait for it to finish, then display the result (VB.NET version)</p>
</div>
<div class="row">
<div class="col-md-4">
<asp:Button ID="btnImport" runat="server" Text="Import" />
</div>
<div class="col-md-4">
<asp:Label ID="lblOutput" runat="server" Text=""></asp:Label>
</div>
</div>
</asp:Content>
... and Default.aspx.vb:
Imports System
Imports System.Data
Imports System.Data.SqlClient
Public Class _Default
Inherits Page
Const ConnectionString As String = "Data Source=YOURSERVERNAMEHERE;Initial Catalog=msdb;Integrated Security=SSPI"
Const JobName As String = "YOURJOBNAMEHERE"
Shared ReadOnly WaitFor As TimeSpan = TimeSpan.FromSeconds(1.0)
Enum JobExecutionResult
Succeeded
FailedToStart
FailedAfterStart
Unknown
End Enum
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
End Sub
Private Sub btnImport_Click(sender As Object, e As EventArgs) Handles btnImport.Click
Dim JobResult As JobExecutionResult = RunJob(JobName)
Select Case JobResult
Case JobExecutionResult.Succeeded
lblOutput.Text = $"SQL Server Agent job, '{JobName}', ran successfully to completion."
Case JobExecutionResult.FailedToStart
lblOutput.Text = $"SQL Server Agent job, '{JobName}', failed to start."
Case JobExecutionResult.FailedAfterStart
lblOutput.Text = $"SQL Server Agent job, '{JobName}', started successfully, but encountered an error."
Case Else
lblOutput.Text = $"Unknown result from attempting to run SQL Server Agent job, '{JobName}'."
End Select
End Sub
Function RunJob(ByVal JobName As String) As JobExecutionResult
Dim JobResult As Integer
Using JobConnection As SqlConnection = New SqlConnection(ConnectionString)
Dim JobCommand As SqlCommand
Dim JobReturnValue As SqlParameter
Dim JobParameter As SqlParameter
JobCommand = New SqlCommand("sp_start_job", JobConnection)
JobCommand.CommandType = CommandType.StoredProcedure
JobReturnValue = New SqlParameter("#RETURN_VALUE", SqlDbType.Int)
JobReturnValue.Direction = ParameterDirection.ReturnValue
JobCommand.Parameters.Add(JobReturnValue)
JobParameter = New SqlParameter("#job_name", SqlDbType.VarChar)
JobParameter.Direction = ParameterDirection.Input
JobCommand.Parameters.Add(JobParameter)
JobParameter.Value = JobName
JobConnection.Open()
Try
JobCommand.ExecuteNonQuery()
JobResult = CInt(JobCommand.Parameters("#RETURN_VALUE").Value)
Catch ex As SqlException
JobResult = -1
End Try
End Using
If JobResult <> 0 Then
Return JobExecutionResult.FailedToStart
End If
While True
Using JobConnection2 As SqlConnection = New SqlConnection(ConnectionString)
Dim JobCommand2 As SqlCommand = New SqlCommand("sp_help_jobactivity", JobConnection2)
JobCommand2.CommandType = CommandType.StoredProcedure
Dim JobReturnValue2 As SqlParameter = New SqlParameter("#RETURN_VALUE", SqlDbType.Int)
JobReturnValue2.Direction = ParameterDirection.ReturnValue
JobCommand2.Parameters.Add(JobReturnValue2)
Dim JobParameter2 As SqlParameter = New SqlParameter("#job_name", SqlDbType.VarChar)
JobParameter2.Direction = ParameterDirection.Input
JobCommand2.Parameters.Add(JobParameter2)
JobParameter2.Value = JobName
JobConnection2.Open()
Dim rdr As SqlDataReader = JobCommand2.ExecuteReader()
While rdr.Read()
Dim Msg As Object = rdr("message")
Dim Run_Status As Object = rdr("run_status")
If Not IsDBNull(Msg) Then
Dim Message As String = TryCast(Msg, String)
Dim RunStatus As Integer? = Run_Status
If Message IsNot Nothing AndAlso Message.StartsWith("The job succeeded") _
AndAlso RunStatus.HasValue AndAlso RunStatus.Value = 1 Then
Return JobExecutionResult.Succeeded
ElseIf Message IsNot Nothing AndAlso Message.StartsWith("The job failed") Then
Return JobExecutionResult.FailedAfterStart
ElseIf RunStatus.HasValue AndAlso RunStatus.Value = 1 Then
Return JobExecutionResult.Unknown
End If
End If
End While
End Using
System.Threading.Thread.Sleep(WaitFor)
End While
End Function
End Class
Note that this solution is synchronous: the postback won't return until the SQL Server Agent job finishes. If someone has a better solution, please feel free to post it.
Related
I'm facing very un natural problem suddenly. I have DropDownList with autopostback is true. Postback executes a method which populates other things onpage according to selection. Now When I select any value first time from that dropdown then page gets postback but nothing get populate but from second time it works fine. Even I put breakpoint on that dropdown & it's not even hitting breakpoint for first postback.
<asp:DropDownList ID="ClientCode" runat="server" ClientIDMode="Static" CssClass="field-pitch" AutoPostBack="true"></asp:DropDownList>
Private Sub ClientCode_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ClientCode.SelectedIndexChanged
Me.populateConsignerDetails()
End Sub
Private Sub populateConsignerDetails()
Try
Dim str As String = "SELECT * FROM clientsDetails WHERE clientID = #clientID"
con.Open()
Dim cmd As New MySqlCommand(str, con)
cmd.Parameters.AddWithValue("#clientID", ClientCode.SelectedItem.ToString)
Dim da As New MySqlDataAdapter(cmd)
Dim dt As New DataTable
da.Fill(dt)
con.Close()
Dim payingParty As String = String.Empty
If dt.Rows.Count > 0 Then
consignerName.Text = dt.Rows(0)("clientName").ToString
consignerAddress.Text = dt.Rows(0)("companyAddress").ToString
consignerMobile1.Text = dt.Rows(0)("contactNumber1").ToString
consignerCity.Text = dt.Rows(0)("city").ToString
consignerState.Text = dt.Rows(0)("state").ToString
consignerPinCode.Text = dt.Rows(0)("pinCode").ToString
End If
Catch ex As Exception
Response.Write(ex)
End Try
End Sub
Update
Private Sub myadmin_shipment_details2_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
populateClient()
End If
End Sub
Private Sub populateClient()
Using conn As New MySqlConnection()
conn.ConnectionString = ConfigurationManager _
.ConnectionStrings("conio").ConnectionString()
Using cmd As New MySqlCommand()
cmd.CommandText = "Select * from clientsDetails where status = 'active'"
cmd.Connection = conn
conn.Open()
Using sdr As MySqlDataReader = cmd.ExecuteReader()
While sdr.Read()
Dim item As New ListItem()
item.Text = sdr("clientID").ToString()
item.Value = sdr("ClientName").ToString()
ClientCode.Items.Add(item)
End While
End Using
conn.Close()
End Using
End Using
End Sub
I want to get the sum of the selected items in the listbox and display them in a label but i am always getting 0,i also want to put the selected items in another label too which is also not working.
Here is what the code look like:
Dim sum As Integer
Dim Items1 As String = "None"
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Label2.Text = Request.QueryString("Name").ToString()
Dim connetionString As String = Nothing
Dim connection As SqlConnection
Dim command As SqlCommand
Dim adapter As New SqlDataAdapter()
Dim ds As New DataSet()
Dim sql As String
connetionString = "Data Source=.;Initial Catalog=Shop;integrated security=true"
sql = "select PhoneName,PhonePrice from SmartPhones"
connection = New SqlConnection(connetionString)
connection.Open()
command = New SqlCommand(sql, connection)
adapter.SelectCommand = command
adapter.Fill(ds)
adapter.Dispose()
command.Dispose()
connection.Close()
ListBox1.DataSource = ds.Tables(0)
ListBox1.DataTextField = "PhoneName"
ListBox1.DataValueField = "PhonePrice"
ListBox1.DataBind()
End Sub
code where the display should happen:
Protected Sub Button2_Click(sender As Object, e As EventArgs) Handles TotalPrice.Click
sum = 0 'reset sum to 0
For Each i As Integer In ListBox1.GetSelectedIndices
Dim CurrentItem As ListItem = ListBox1.Items(i)
sum = sum + CInt(CurrentItem.Value)
Items1 = Items1 + " , " + CStr(CurrentItem.Text)
Next
Label3.Text = Items1
Label1.Text = sum
End Sub
Here is the page Design and the Page On the web Respectively:
PhoneName is of type varchar in database & PhonePrice is of type integer (Both Filled correctly).
ListBox code:
<asp:ListBox ID="ListBox1" runat="server" SelectionMode="Multiple" ></asp:ListBox>
What's the reason that the code won't give me the desired result?
What is happening is that when you click TotalPrice a postback is performed (What is a postback?). If you look at the ASP.NET page lifecycle you will see that the Load event happens before the postback event handling (e.g. your Sub Button2_Click).
So, you click the button, it runs the Me.Load handler and... your list is reset before the click handler gets a chance to run.
There is a property you can check to see if the page is running as a result of a postback: Page.IsPostBack.
So all you need to do is check it to see if you need to populate the list:
Sub FillItemsList()
Dim connectionString As String = "Data Source=.;Initial Catalog=Shop;integrated security=true"
Dim dt As New DataTable()
Using connection As New SqlConnection(connectionString)
Dim sql As String = "SELECT PhoneName,PhonePrice FROM SmartPhones"
Using adapter As New SqlDataAdapter(sql, connection)
adapter.Fill(dt)
End Using
End Using
ListBox1.DataSource = dt
ListBox1.DataTextField = "PhoneName"
ListBox1.DataValueField = "PhonePrice"
ListBox1.DataBind()
End Sub
Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Label2.Text = Request.QueryString("Name").ToString()
If Not Page.IsPostBack Then
FillItemsList()
End If
End Sub
I am having an issue with my login page. I am not getting any errors so am not able to know where the problem is?
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Login.Click
'connection string
Dim mysqlconn As MySqlConnection = New MySqlConnection("server=localhost;user id=root;Password=123;database=users;persist security info=False")
Dim cmd As New MySqlCommand
Dim da As New MySqlDataAdapter
Dim mydata As New DataTable
Dim reader As MySqlDataReader
Try
mysqlconn.Open()
Dim query As String
query = "SELECT * FROM login_form where Username = '" & rfvUser.Text & "' and Password='" & rfvPWD.Text & "'"
cmd = New MySqlCommand(query, mysqlconn)
reader = cmd.ExecuteReader
While reader.Read()
If rfvUser.Text = "admin" And rfvPWD.Text = "admin" Then
Me.Session("User") = Me.rfvUser.Text
Server.Transfer("Admin.aspx")
ElseIf (rfvUser.Text = reader("UserName").ToString()) And (rfvPWD.Text = reader("Password").ToString()) Then
Me.Session("User") = Me.rfvUser.Text
Server.Transfer("Ersal_send.aspx")
Else
ClientScript.RegisterStartupScript(Page.[GetType](), "validation", "<script language='javascript'>alert('Invalid Username or Password')</script>")
reader.Close()
End If
End While
Catch ex As Exception
MsgBox(ex.Message)
Finally
mysqlconn.Dispose()
End Try
End Sub
End Class
Have you tried running the query directly via a SQL client? If your query is not returning any rows, then your procedure will simply exit without any errors as it will never enter the While loop.
Another advice: It is never a good idea to pass user input directly into a query. This leads to SQL injection. Use parameterised queries. Google for it.
I have a separate page where I use the Server.HTMLEncode feature to encode HTML a user has entered inside of a HTMLEditorExtender on a TextBox.
I am trying to insert this HTML into a repeater like so:
<asp:Repeater id="articleList" runat="server">
<ItemTemplate>
<div class="itemtemplate">
<h2><%#Container.DataItem("Title")%></h2>
<h5>Category:</h5> <%#Container.DataItem("Category")%><br />
<%#Container.DataItem("decodedHTML")%>
<%#Container.DataItem("UserName")%>
<%#Container.DataItem("DateOfPost")%>
</div>
</ItemTemplate>
<AlternatingItemTemplate>
<div class="altitemtemplate">
<h2><%#Container.DataItem("Title")%></h2>
<h5>Category:</h5> <%#Container.DataItem("Category")%><br />
<%#Container.DataItem("decodedHTML")%>
<%#Container.DataItem("UserName")%>
<%#Container.DataItem("DateOfPost")%>
</div>
</AlternatingItemTemplate>
</asp:Repeater>
And my code behind:
Sub displayArticles()
Dim conn As New OleDb.OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
conn.Open()
Dim cmd As New OleDbCommand("SELECT * FROM [UserArticles] ORDER BY DateOfPost DESC", conn)
Dim inputString As String = "HTMLBody"
Dim decodedHTML As String = Server.HtmlDecode(inputString)
articleList.DataSource = cmd.ExecuteReader()
articleList.DataBind()
conn.Close()
End Sub
"HTMLBody" is the name of the field in my database with the encoded HTML in.
Unfortunately, I am receiving the error
"IndexOutOfRangeException was unhandled by user code".
There is obviously a problem here referring to the string decodedHTML in my Container.DataItem statement, so what am I doing wrong?
EDIT: code from the other page where the html is encoded:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If String.IsNullOrEmpty(TextBox1.Text) Then
ErrorMessage.Visible = True
ErrorMessage.Text = "Your submission is blank. Please write your article first"
Else
Dim oleDbConn As New OleDb.OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
Dim SqlString As String = "Insert into UserArticles(Title,Category,UserName,DateOfPost,HTMLPost) Values (#f1,#f2,#f3,#f4,#f5)"
Dim HTMLEncode As String = Server.HtmlEncode(TextBox1.Text)
Dim cmd As OleDbCommand = New OleDbCommand(SqlString, oleDbConn)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("#f1", ArticleTitle.Text)
cmd.Parameters.AddWithValue("#f2", CategoryDropDown.SelectedValue)
cmd.Parameters.AddWithValue("#f3", User.Identity.Name)
cmd.Parameters.AddWithValue("#f4", DateTime.Now.Date)
cmd.Parameters.AddWithValue("#f5", HTMLEncode)
oleDbConn.Open()
cmd.ExecuteNonQuery()
TextBox1.Text = Nothing
ArticleTitle.Text = Nothing
CategoryDropDown.ClearSelection()
End If
End Sub
From the looks of it, decodedHTML is just a string which you are creating in the code. This is not accessible through your .aspx page.
You should just be able to update your .aspx markup to;
<%#Server.HtmlDecode(Container.DataItem("[COLUMN_NAME"))%>
Where [COLUMN_NAME] is the actual Table Column which holds the encoded html value.
I am trying to learn how to do this .NET frameworks for my job and what not..... I can't figure why it isn't working.
Error occurs here:
myCommand.Connection.Open()
I am assuming it is because of how I am doing....
Dim idbox As TextBox = E.Item.Cells(numCols - 1).Controls(0)
myCommand.Parameters("#Id").Value = Integer.Parse(idbox.Text)
Source:
<%# Import Namespace="System.Data" %>
<%# Import Namespace="System.Data.SqlClient" %>
<%# Import Namespace="System.Data.OleDb" %>
<html>
<script language="VB" runat="server">
Dim myConnection As SqlConnection
' Create a connection to the "pubs" SQL database located on the
' local computer.
Sub Page_Load(Src As Object, E As EventArgs)
If Session("Admin") <> True Then
Response.Redirect("login.aspx")
Else
Dim myConnection As SqlConnection = New SqlConnection("CONNECTION INFO")
' Determine whether this page is a postback. If it is not a
' postback, call BindGrid.
If Not IsPostBack Then
Dim dbconn As OleDbConnection
Dim sql As String
Dim dbcomm As OleDbCommand
Dim dbread As OleDbDataReader
dbconn = New OleDbConnection("CONNECTION INFO")
dbconn.Open()
sql = "SELECT Name FROM TestData"
dbcomm = New OleDbCommand(sql, dbconn)
dbread = dbcomm.ExecuteReader()
DropDownList1.Items.Clear()
While dbread.Read
DropDownList1.Items.Add(dbread(0))
End While
dbread.Close()
dbconn.Close()
BindGrid()
End If
End If
End Sub
' Create an index to the DataGrid row that is clicked and
' call BindGrid.
Sub MyDataGrid_Edit(sender As Object, E As DataGridCommandEventArgs)
MyDataGrid.EditItemIndex = CInt(E.Item.ItemIndex)
BindGrid()
End Sub
' Cancel resets the index to the row's previous settings.
Sub MyDataGrid_Cancel(sender As Object, E As DataGridCommandEventArgs)
MyDataGrid.EditItemIndex = -1
BindGrid()
End Sub
' When the Update link is clicked, build a SQL UPDATE command,
' connect to the database, update the row's information in the
' database, and rebind the DataGrid to show the updated information.
Public Sub MyDataGrid_Update(sender As Object, _
E As DataGridCommandEventArgs)
Dim updateCmd As String = "UPDATE TestData SET AdoptedNum = #AdoptedNum, PrecinctNum = #PrecinctNum WHERE Id = #Id"
Dim myCommand As SqlCommand = New SqlCommand(updateCmd, myConnection)
myCommand.Parameters.Add(New SqlParameter("#Name", SqlDbType.VarChar))
myCommand.Parameters.Add(New SqlParameter("#PrecinctNum", SqlDbType.Int))
myCommand.Parameters.Add(New SqlParameter("#AdoptedNum", SqlDbType.Int))
myCommand.Parameters.Add(New SqlParameter("#Id", SqlDbType.Int))
' Initialize the SqlCommand "#ID" parameter to the ID of the row
' that must be clicked.
Dim numCols As Integer = E.Item.Cells.Count
Dim i As Integer
Dim colvalue As String
Dim txtBox As TextBox
Dim idbox As TextBox = E.Item.Cells(numCols - 1).Controls(0)
myCommand.Parameters("#Id").Value = Integer.Parse(idbox.Text)
' Create an array of column names.
Dim cols() As String = {"#Name", "#PrecinctNum", "#AdoptedNum", "#Id"}
' Skipping the first, second, and last columns, iterate through the
' columns, checking for empty values. If an empty value is found,
' display a message box. Also initialize the SqlCommand
' parameter values.
For i = 2 To numCols - 1
txtBox = E.Item.Cells(i).Controls(0)
colvalue = txtBox.Text
If (i < numCols And colvalue = "") Then
Message.InnerHtml = "ERROR: Null values not allowed for " _
& "Author ID, Name or Phone"
Message.Style("color") = "red"
Exit Sub
End If
myCommand.Parameters(cols(i - 1)).Value = colvalue
Next i
' Connect to the database and update the information.
myCommand.Connection.Open()
' Test whether the data was updated, and display the
' appropriate message to the user.
Try
myCommand.ExecuteNonQuery()
Message.InnerHtml = "<b>Record Updated.</b><br>"
MyDataGrid.EditItemIndex = -1
Catch ex As SqlException
If ex.Number = 2627 Then
Message.InnerHtml = "ERROR: A record already exists" _
& " with the same primary key"
Else
Message.InnerHtml = "ERROR: Could not update record," _
& " please ensure the fields are correctly filled out."
Message.Style("color") = "red"
End If
End Try
' Close the connection.
myCommand.Connection.Close()
' Rebind the DataGrid to show the updated information.
BindGrid()
End Sub
' The BindGrid procedure connects to the database and implements
' a SQL SELECT query to get all the data in the "Authors" tablea.
Public Sub BindGrid()
Dim myConnection As SqlConnection = _
New SqlConnection("CONNECTION INFO")
Dim myCommand As SqlDataAdapter = New SqlDataAdapter("SELECT *" _
& " FROM TestData WHERE Name='" & DropDownList1.SelectedValue & "'", myConnection)
Dim ds As DataSet= New DataSet()
myCommand.Fill(ds)
MyDataGrid.DataSource = ds
MyDataGrid.DataBind()
End Sub
Protected Sub MyDataGrid_SelectedIndexChanged(sender As Object, e As System.EventArgs)
End Sub
Sub DropDownList1_SelectedIndexChanged(sender As Object, e As EventArgs)
BindGrid()
End Sub
</script>
<body style="font: 10pt verdana">
<form id="Form1" runat="server"><center>
<h3><font face="Verdana">Updating a Row of Data.</font></h3>
<span id="Message" EnableViewState="false"
style="font:arial 11pt;" runat="server"/><p>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
<ASP:DataGrid id="MyDataGrid" runat="server"
Width="800"
BackColor="#ccccff"
BorderColor="black"
ShowFooter="false"
CellPadding=3
CellSpacing="0"
Font-Name="Verdana"
Font-Size="8pt"
HeaderStyle-BackColor="#aaaadd"
OnEditCommand="MyDataGrid_Edit"
OnCancelCommand="MyDataGrid_Cancel"
OnUpdateCommand="MyDataGrid_Update"
>
<Columns>
<ASP:EditCommandColumn EditText="Edit" CancelText="Cancel"
UpdateText="Update"/>
</Columns>
</ASP:DataGrid>
</center>
</form>
</body>
</html>
I suspect the problem is you define but never initialize the instance variable myConnection. You define and instantiate a local variable of the same name within the Page_Load function, but that is a distinct and different object than your instance variable.
In your Page_Load, if you change this:
Dim myConnection As SqlConnection = New SqlConnection("CONNECTION INFO")
to this:
myConnection As SqlConnection = New SqlConnection("CONNECTION INFO")
then your instance variable should be initialized and ready for use in your MyDataGrid_Update event handler.
Did this even compile? This wont work because your code has a bug.
SqlCommand won't support myCommand.Connection.Open()