복붙노트

[SQL] 어떻게 SQL 작업이 성공적으로 실행 여부를 C #의 여부를 확인하는

SQL

어떻게 SQL 작업이 성공적으로 실행 여부를 C #의 여부를 확인하는

나는 SQL 작업을 실행하는 C #을 방법이 있습니다. 그것은 성공적으로 SQL 작업을 실행합니다. 그리고 코드는 완벽하게 작동합니다.

그리고이 표준 SQL 저장 프로 시저 msdb.dbo.sp_start_job을 사용하고 있습니다.

여기 내 코드입니다 ..

public int ExcecuteNonquery()
{
     var result = 0;
     using (var execJob =new SqlCommand())
     {
          execJob.CommandType = CommandType.StoredProcedure;
          execJob.CommandText = "msdb.dbo.sp_start_job";
          execJob.Parameters.AddWithValue("@job_name", "myjobname");
          using (_sqlConnection)
          {
               if (_sqlConnection.State == ConnectionState.Closed) 
                  _sqlConnection.Open();

               sqlCommand.Connection = _sqlConnection;
               result = sqlCommand.ExecuteNonQuery();

               if (_sqlConnection.State == ConnectionState.Open) 
                 _sqlConnection.Close();
          }
     }
     return result;
}

여기에 작업 내에서 실행하는 SP입니다

ALTER PROCEDURE [Area1].[Transformation]
              AS 
              BEGIN
              SET NOCOUNT ON;

              SELECT NEXT VALUE FOR SQ_COMMON
              -- Transform Master Data
              exec [dbo].[sp_Transform_Address];
              exec [dbo].[sp_Transform_Location];
              exec [dbo].[sp_Transform_Product];
              exec [dbo].[sp_Transform_Supplier];
              exec [dbo].[sp_Transform_SupplierLocation];

              -- Generate Hierarchies and Product References
              exec [dbo].[sp_Generate_HierarchyObject] 'Area1',FGDemand,1;
              exec [dbo].[sp_Generate_HierarchyObject] 'Area1',RMDemand,2;
              exec [dbo].[sp_Generate_Hierarchy] 'Area1',FGDemand,1;
              exec [dbo].[sp_Generate_Hierarchy] 'Area1',RMDemand,2;
              exec [dbo].[sp_Generate_ProductReference] 'Area1',FGDemand,1;
              exec [dbo].[sp_Generate_ProductReference] 'Area1',RMDemand,2;

              -- Transform Demand Allocation BOM 
              exec [Area1].[sp_Transform_FGDemand];
              exec [Area1].[sp_Transform_FGAllocation];
              exec [Area1].[sp_Transform_RMDemand];
              exec [Area1].[sp_Transform_RMAllocation];
              exec [Area1].[sp_Transform_BOM];
              exec [Area1].[sp_Transform_RMDemand_FK];

              -- Transform Purchasing Document Data
              exec [dbo].[sp_Transform_PurchasingDoc];
              exec [dbo].[sp_Transform_PurchasingItem];
              exec [dbo].[sp_Transform_ScheduleLine];


              exec [dbo].[sp_CalculateRequirement] 'Area1'
              exec [dbo].[sp_Create_TransformationSummary] 'Area1'
              -- Trauncate Integration Tables 
              exec [dbo].[sp_TruncateIntegrationTables] 'Area1'

              END

문제는, 심지어 작업이 성공적 여부 그것은 항상 수익을 실행 -1. 어떻게 작업이 성공적으로 실행 여부를 확인할 수 있습니다.

해결법

  1. ==============================

    1.msdb.dbo.sp_start_job를 실행 한 후 리턴 코드는 출력 매개 변수에 매핑됩니다. 당신은 실행하기 전에 매개 변수의 이름을 제어 할 수있는 기회를 갖게 :

    msdb.dbo.sp_start_job를 실행 한 후 리턴 코드는 출력 매개 변수에 매핑됩니다. 당신은 실행하기 전에 매개 변수의 이름을 제어 할 수있는 기회를 갖게 :

    public int StartMyJob( string connectionString )
    {
     using (var sqlConnection = new SqlConnection( connectionString ) )
     {
       sqlConnection.Open( );
       using (var execJob = sqlConnection.CreateCommand( ) )
       {
          execJob.CommandType = CommandType.StoredProcedure;
          execJob.CommandText = "msdb.dbo.sp_start_job";
          execJob.Parameters.AddWithValue("@job_name", "myjobname");
          execJob.Parameters.Add( "@results", SqlDbType.Int ).Direction = ParameterDirection.ReturnValue;      
          execJob.ExecuteNonQuery();
          return ( int ) sqlCommand.Parameters["results"].Value;
        }
      }
    }
    

    이 작업을 수행하려면 리턴 코드의 데이터 유형을 알 필요가 - 그리고 sp_start_job를 들어, SqlDbType.Int을합니다.

    그러나,이 아는 가치가 작업을 시작,의 결과이지만, 작업의 실행 결과가 아닙니다. 작업의 실행 결과를 얻으려면, 당신은 정기적으로 실행할 수 있습니다 :

    msdb.dbo.sp_help_job @jobName
    

    절차에 의해 반환 된 열 중 하나는 last_run_outcome이며, 아마도 당신이 정말로 관심을하는지 들어 있습니다. 여전히 실행중인하면서 5 (알 수없는)입니다.

    각 단계 또는 이전 단계의 결과에 따라 실행되지 않을 수 있습니다 - 작업은 일반적으로 단계는 A 번호입니다. sp_help_jobhistory 지원을 필터를 많이 불리는 또 다른 방법은 특정 호출 및 / 또는 작업 당신에게있는 거 관심의 단계를 지정합니다.

    SQL 예약 된 작업과 같은 작업에 대한 생각을 좋아하는 - 그러나 단지 작업 임시을 시작에서 당신을 유지하는 아무것도 없다 - 정말 인스턴스로 임시 작업의 상관 관계를 많은 지원을 제공하지 않지만 작업 기록입니다 . 날짜는 좋은대로수록 (누군가가 트릭을 알지 못하는 경우 나도 몰라.)에 대한 있습니다

    작업이 직전에 그것을 실행하는 임시 작업을 만들어 어디는 현재 임시 실행이 반환되는 경우에만 실행하므로, 본 적이있다. 하지만 당신은 결코 다시 실행하려고하지 않습니다 주위에 누워 중복 또는 거의 중복 작업의 많은 끝. 당신이 길을 가면 뭔가 당신이 나중에 청소에 계획해야합니다.

    _sqlConnection 변수의 사용에주의. 당신은 그렇게하고 싶지 않아. 이 메서드가 호출되기 전에 그것은 귀하의 코드를 처분하는이 있지만 분명히 다른 곳에서 만들었습니다. 즉 나쁜 주주입니다. 당신은 더 나은 오프 단지 연결을 생성하고 그것을 같은 방법으로 폐기하고 있습니다. 아마 이미 켜져 - 빠른 연결을 위해 SQL 연결 풀링에 의존하고 있습니다.

    그리고 좀 편집을 엉망 - 또한 - 당신이 게시 코드 - 당신이 execJob 시작하지만 SqlCommand를 전환 것 같습니다. 난 당신이 모든 방법을 통해 execJob을 의미 가정 - 그는 예를 반영합니다.

  2. ==============================

    2.SqlCommand.ExecuteNonQuery 방법에 대한 MSDN에서 :

    SqlCommand.ExecuteNonQuery 방법에 대한 MSDN에서 :

    이 라인에서 :

    result = sqlCommand.ExecuteNonQuery();
    

    당신은 INT 변수에 명령에 의해 영향을받는 행의 수와 그 저장을 반환하고 싶지만 구문의 유형이기 때문에 그것을 반환 있도록 -1 선택합니다. 당신은 INSERT 또는 DELETE 또는 UPDATE 문으로 테스트하면 올바른 결과를 얻을 것이다.

    당신은 SELECT 명령에 의해 영향을받는 행의 수를 얻을 당신이 이런 식으로 뭔가를 시도 할 수있는 int 변수에 저장하려면 그런데 :

    select count(*) from jobs where myjobname = @myjobname
    

    그리고 정확한 결과를 얻을 수 ExecuteScalar는을 사용합니다 :

    result = (int)execJob.ExecuteScalar();
    
  3. ==============================

    3.당신은 저장 프로 시저 msdb.dbo.sp_help_job를 실행해야

    당신은 저장 프로 시저 msdb.dbo.sp_help_job를 실행해야

         private int CheckAgentJob(string connectionString, string jobName) {
            SqlConnection dbConnection = new SqlConnection(connectionString);
            SqlCommand command = new SqlCommand();
            command.CommandType = System.Data.CommandType.StoredProcedure;
            command.CommandText = "msdb.dbo.sp_help_job";
            command.Parameters.AddWithValue("@job_name", jobName);
            command.Connection = dbConnection;
            using (dbConnection)
            {
                dbConnection.Open();      
                using (command){
                    SqlDataReader reader = command.ExecuteReader();
                    reader.Read();
                    int status = reader.GetInt32(21); // Row 19 = Date Row 20 = Time 21 = Last_run_outcome
                    reader.Close();
                    return status;
                }
            }
         }
    
    enum JobState { Failed = 0, Succeeded = 1, Retry = 2, Cancelled = 3, Unknown = 5};
    

    당신이 답을 얻을 때까지, 알 수없는 폴링을 유지합니다. 그것은이 성공 희망하자 :-)

  4. from https://stackoverflow.com/questions/31337492/how-to-identify-whether-sql-job-is-successfully-executed-or-not-in-c-sharp by cc-by-sa and MIT license