none
Ejecutar Job en DB SqlServer RRS feed

  • Pregunta

  • hola

    Para ejecutar un trabajo desde mi aplicacion ejecuto el siguiente codigo, Existe una forma de saber si el trabajo termino con exito o simplemente termino ??? es para mandar a ejecutar una rutina en el momento que el trabajo finalize....


        Public Function IniciarTrabajo(ByVal nombre_job As String) As Boolean
            Dim bandera As Boolean = False
            Dim sql As String = "USE msdb EXEC sp_start_job @job_name = @nombre_job"
            Dim Conexion As SqlConnection = New SqlConnection(cadenaConexion)
            Dim comando As SqlCommand = New SqlCommand(sql, Conexion)
            Try
                comando.Connection.Open()
                comando.Parameters.Clear()
                comando.Parameters.AddWithValue("@nombre_job", nombre_job)
                comando.ExecuteNonQuery()
                comando.Connection.Close()
                bandera = True
            Catch ex As SqlException
                comando.Connection.Close()
            End Try
            Return bandera
        End Function


    EFRAIN MEJIAS C VALENCIA - VENEZUELA

    miércoles, 14 de octubre de 2015 16:01

Respuestas

  • "Efrain Mejias Castillo" escribió:

    > en realidad lo que nesecito es  saber si el trabajo finalizo....
    >
    > por ejemplo con tu codigo , si mando a ejecutar el trabajo y este tarda 4
    > minutos en finalizar, la siguiente instruccion despues de
    >
    > Dim resultado As Int32 = comando.ExecuteNonQuery()
    >
    > se ejecuta 4 minutos despues??? si es asi me sirve de lo contrario no

    En principio el método ExecuteNonQuery es síncrono, lo que significa que el subproceso actual de tu aplicación se bloqueará hasta que finalice el trabajo que le has dicho que ejecute dicho método. ¿Que tarda 4, 10, 30 minutos? Hasta que no transcurra dicho tiempo no se ejecutará la siguiente línea de código existente tras el método ExecuteNonQuery, salvo que se haya producido un error antes de finalizar el trabajo, en cuyo caso el flujo de ejecución pasará al bloque Catch. existente en la función IniciarTrabajo.

    De todas maneras, yo no te aconsejaría implementar el método IniciarTrabajo tal cual lo estás haciendo, porque si se produce una excepción, NUNCA SERÁS CAPAZ de averiguar lo que realmente ha ocurrido, porque te estás limitando únicamente a establecer el valor False a la variable bandera en el bloque Catch, con lo cual el método devolverá el valor False lo que significará que el método no se ha ejecutado satisfactoriamente, pero no sabrás el motivo por el cual ha fallado.

    Si no te interesa conocer el número de registros afectados por la ejecución del método ExecuteNonQuery, el método IniciarTrabajo debería ser un procedimiento Sub en lugar de Function, al menos como yo entiendo que se deberían de implementar éstos métodos:

        Public Sub IniciarTrabajo(ByVal nombre_job As String)
    
            Using conexion As New SqlConnection(cadenaConexion)
                Dim comando As SqlCommand = conexion.CreateCommand()
                comando.CommandText = "USE msdb EXEC sp_start_job @job_name = @nombre_job"
                comando.Parameters.AddWithValue("@nombre_job", nombre_job)
                comando.Connection.Open()
                comando.ExecuteNonQuery()
            End Using
    
            ' Si se ha llegado hasta aquí es porque el trabajo ha
            ' finalizado y no se ha producido una excepción.
            '
    
        End Sub
    

    Y la posible excepción la tienes que atrapar en el código que llama a la función IniciarTrabajo, con lo cual estarás conociendo lo que realmente ha ocurrido para que falle el método:

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Try
                IniciarTrabajo("nombre trabajo")
                MessageBox.Show("El trabajo ha finalizado y no ha producido error alguno.")
    
            Catch ex As Exception
                ' Se ha producido un error
                MessageBox.Show(ex.Message)
    
            End Try
    
        End Sub
    

    Se comprende que el procedimiento 'sp_start_job' estará bien diseñado y hará bien su trabajo, por lo que únicamente te tendrás que preocupar de la posible excepción que se pueda producir.


    Enrique Martínez Montejo
            [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    viernes, 16 de octubre de 2015 16:06
    Moderador

Todas las respuestas

  • Hola Efrain Mejias Castillo,

    ¿Que acciones realiza la tarea? Recuerda que el método ExecuteNonQuery retorna el número de filas afectadas (en caso se hayan realizado operaciones de I, U, D) podrías usar ese valor para validar si la tarea se efectuó correctamente.

    Dim resultado As Int32 = comando.ExecuteNonQuery()
    
    IF (resultado = 0) Then
    Begin
            'Tarea no realizada
    End IF

    En cualquier otro caso, la tarea debería escribir en alguna tabla un valor en caso haya sido exitosa o no, lo que tendrías que hacer es leer esa tabla para saber el resultado de la operación.

    miércoles, 14 de octubre de 2015 16:10
  • Hola Willams Morales

    ¿Que acciones realiza la tarea?

    Realiza varias ...pero en realidad lo que nesecito es  saber si el trabajo finalizo....

    por ejemplo con tu codigo , si mando a ejecutar el trabajo y este tarda 4 minutos en finalizar, la siguiente instruccion despues de

    Dim resultado As Int32 = comando.ExecuteNonQuery()

    se ejecuta 4 minutos despues??? si es asi me sirve de lo contrario no


    EFRAIN MEJIAS C VALENCIA - VENEZUELA

    miércoles, 14 de octubre de 2015 16:39
  • "Efrain Mejias Castillo" escribió:

    > en realidad lo que nesecito es  saber si el trabajo finalizo....
    >
    > por ejemplo con tu codigo , si mando a ejecutar el trabajo y este tarda 4
    > minutos en finalizar, la siguiente instruccion despues de
    >
    > Dim resultado As Int32 = comando.ExecuteNonQuery()
    >
    > se ejecuta 4 minutos despues??? si es asi me sirve de lo contrario no

    En principio el método ExecuteNonQuery es síncrono, lo que significa que el subproceso actual de tu aplicación se bloqueará hasta que finalice el trabajo que le has dicho que ejecute dicho método. ¿Que tarda 4, 10, 30 minutos? Hasta que no transcurra dicho tiempo no se ejecutará la siguiente línea de código existente tras el método ExecuteNonQuery, salvo que se haya producido un error antes de finalizar el trabajo, en cuyo caso el flujo de ejecución pasará al bloque Catch. existente en la función IniciarTrabajo.

    De todas maneras, yo no te aconsejaría implementar el método IniciarTrabajo tal cual lo estás haciendo, porque si se produce una excepción, NUNCA SERÁS CAPAZ de averiguar lo que realmente ha ocurrido, porque te estás limitando únicamente a establecer el valor False a la variable bandera en el bloque Catch, con lo cual el método devolverá el valor False lo que significará que el método no se ha ejecutado satisfactoriamente, pero no sabrás el motivo por el cual ha fallado.

    Si no te interesa conocer el número de registros afectados por la ejecución del método ExecuteNonQuery, el método IniciarTrabajo debería ser un procedimiento Sub en lugar de Function, al menos como yo entiendo que se deberían de implementar éstos métodos:

        Public Sub IniciarTrabajo(ByVal nombre_job As String)
    
            Using conexion As New SqlConnection(cadenaConexion)
                Dim comando As SqlCommand = conexion.CreateCommand()
                comando.CommandText = "USE msdb EXEC sp_start_job @job_name = @nombre_job"
                comando.Parameters.AddWithValue("@nombre_job", nombre_job)
                comando.Connection.Open()
                comando.ExecuteNonQuery()
            End Using
    
            ' Si se ha llegado hasta aquí es porque el trabajo ha
            ' finalizado y no se ha producido una excepción.
            '
    
        End Sub
    

    Y la posible excepción la tienes que atrapar en el código que llama a la función IniciarTrabajo, con lo cual estarás conociendo lo que realmente ha ocurrido para que falle el método:

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Try
                IniciarTrabajo("nombre trabajo")
                MessageBox.Show("El trabajo ha finalizado y no ha producido error alguno.")
    
            Catch ex As Exception
                ' Se ha producido un error
                MessageBox.Show(ex.Message)
    
            End Try
    
        End Sub
    

    Se comprende que el procedimiento 'sp_start_job' estará bien diseñado y hará bien su trabajo, por lo que únicamente te tendrás que preocupar de la posible excepción que se pueda producir.


    Enrique Martínez Montejo
            [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    viernes, 16 de octubre de 2015 16:06
    Moderador
  • Hola

    Enrique M. Montejo

    Ya el trabajo tiene tiempo ejecutandose de forma perfecta , ahora agregue un boton a la aplicacion para ejecutarlo en un momento dado .

    Lo que pasa es que cuando lo mando a ejecutar manualmente desde el ManaGerSql desde que inicia el trabajo hasta que finaliza segun el ManagerSQl trascurren 7 segundos.... ahora en mi aplicacion hago esto y el message de transaccion exitosa me sale instantaneo por eso no me convence de que ya el trabajo este finalizado

        Private Sub ActualizarProveedoresDesdeGPToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ActualizarProveedoresDesdeGPToolStripMenuItem.Click
            Dim Metodo As ClaseCompras = New ClaseCompras()
            If Metodo.IniciarTrabajo("UpdateMaestroProveedor") Then
                MessageBox.Show("TRANSACCION EXITOSA", "INFORMACION DEL SISTEMA", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("TRANSACCION FALLIDA", "INFORMACION DEL SISTEMA", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End Sub

    Public Function IniciarTrabajo(ByVal nombre_job As String) As Boolean
            Dim bandera As Boolean = False
            Dim sql As String = "USE msdb EXEC sp_start_job @job_name = @nombre_job"
            Dim Conexion As SqlConnection = New SqlConnection(cadenaConexion)
            Dim comando As SqlCommand = New SqlCommand(sql, Conexion)
            Try
                comando.Connection.Open()
                comando.Parameters.Clear()
                comando.Parameters.AddWithValue("@nombre_job", nombre_job)
                comando.ExecuteNonQuery()
                comando.Connection.Close()
                bandera = True
            Catch ex As SqlException
                comando.Connection.Close()
            End Try
            Return bandera
        End Function


    EFRAIN MEJIAS C VALENCIA - VENEZUELA

    viernes, 16 de octubre de 2015 17:49
  • "Efrain Mejias Castillo" escribió:

    > Lo que pasa es que cuando lo mando a ejecutar manualmente desde el ManaGerSql
    > desde que inicia el trabajo hasta que finaliza segun el ManagerSQl trascurren
    > 7 segundos.... ahora en mi aplicacion hago esto y el message de transaccion
    > exitosa me sale instantaneo por eso no me convence de que ya el trabajo este
    > finalizado

    ¿Dudas de la rapidez en que una aplicación de Visual Basic .NET puede realizar un trabajo? ;-)

    Con independencia que tarde más o menos que el Administrador de SQL Server, lo que tienes que comprobar es si el trabajo se ha realizado satisfactoriamente, aunque éste se haya realizado en un abrir y cerrar de ojos. ;-)


    Enrique Martínez Montejo
            [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    viernes, 16 de octubre de 2015 18:02
    Moderador
  • Gracias 

    Enrique M. Montejo

    ¿Dudas de la rapidez en que una aplicación de Visual Basic .NET puede realizar un trabajo? 

    Mando a ejecutar el Job desde mi aplicacion ...pero aun asi el motor de la db es el que ejecuta las intrucciones o me equivoco ??

    BUENO , el trabajo consta de 5 pasos y las tablas tienen un regular numero de registros ,el trabajo siempre se ejecuta satisfactoriamente tiene tiempo en produccion.

    Como te digo lo que nesecito es que cuando mande a ejecutar la siguiente linea de codigo ya este finalizado...lo voy a hacer aplicando tu consejo

    En principio el método ExecuteNonQuery es síncrono, lo que significa que el subproceso actual de tu aplicación se bloqueará hasta que finalice el trabajo que le has dicho que ejecute dicho método.

    pènse en un Timer 100000  pero estoy buscando buena practica.


    EFRAIN MEJIAS C VALENCIA - VENEZUELA


    viernes, 16 de octubre de 2015 20:02
  • Pero, ¿para qué quieres colocar un Timer? Tal cual estás ejecutando el código, hasta que no finalice de ejecutarse el método ExecuteNonQuery (el procedimiento almacenado que has llamado) el flujo del código no ejecutarà la siguiente línea existente después de ExecuteNonQuery.

    >  ...pero aun asi el motor de la db es el que ejecuta las intrucciones o me equivoco ??

    Así es, el motor de datos de SQL Server es el que ejecuta el procedimiento almacenado o consulta invocada, pero sin necesidad de utilizar para nada el Administrador de SQL Server.

    Enrique Martínez Montejo
            [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    viernes, 16 de octubre de 2015 22:44
    Moderador
  • Pero, ¿para qué quieres colocar un Timer? 

    Fue una idea que surgio antes de el post solo lo comentaba

    Como te dije el codigo quedara basado en q 

    El método ExecuteNonQuery es síncrono, lo que significa que el subproceso actual de tu aplicación se bloqueará hasta que finalice el trabajo


    EFRAIN MEJIAS C VALENCIA - VENEZUELA

    viernes, 16 de octubre de 2015 22:55