Просто Exe c SP работает, но Insert в таблицу Exe c SP заходит в бесконечный цикл - PullRequest
0 голосов
/ 08 мая 2020

Вопрос 1)

Планируем отключить XP CMDSHELL в SQL. Есть ли альтернатива методу, который я использую ниже:

Вопрос 2)

Ниже SP

1. Создает новое SQL задание каждый раз 2. Запускает CMD команда, переданная ему из параметра 3 SP. Наконец, SP возвращает результат

USE [Test]
GO
/****** Object:  StoredProcedure [dbo].[CMDSHELL_ALTERNATIVE]    Script Date: 5/8/2020 5:44:39 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CMDSHELL_ALTERNATIVE]

    @Command varchar(200),
    @InvokedBySP varchar(100) = 'AdhocCalling'
AS
BEGIN
DECLARE @OutputFileName varchar(max)
DECLARE @OutputFilePath varchar(max)
DECLARE @JobOutcome int = 5
DECLARE @JobMessage varchar(max)
DECLARE @TodayDate DATE = GETDATE()
DECLARE @JobExecutionTime DATETIME
DECLARE @RandomeNumber BIGINT = CAST(RAND() * 1000000 AS BIGINT)
DECLARE @JobName varchar(100) = 'CMDSHELL_JOB_'+ CAST(@TodayDate AS VARCHAR)+'_'+CAST(@RandomeNumber AS VARCHAR)
SET @OutputFilePath ='C:\Users\OutputFiles\'
SET @OutputFileName = @JobName+'.txt'
DECLARE @FullOutputFilePathName varchar(max) = @OutputFilePath+@OutputFileName
DECLARE @jobId BINARY(16)
EXEC  msdb.dbo.sp_add_job @job_name=@JobName, 
        @enabled=1, 
        @notify_level_eventlog=0, 
        @notify_level_email=2, 
        @notify_level_page=2, 
        @delete_level=0, 
        @category_name=N'[Uncategorized (Local)]', 
        @owner_login_name=N'sa', @job_id = @jobId OUTPUT
EXEC msdb.dbo.sp_add_jobserver @job_name=@JobName, @server_name = N'(local)'

EXEC msdb.dbo.sp_add_jobstep @job_name=@JobName, @step_name=N'step-1', 
        @step_id=1, 
        @cmdexec_success_code=0, 
        @on_success_action=1, 
        @on_fail_action=2, 
        @retry_attempts=0, 
        @retry_interval=0, 
        @os_run_priority=0, @subsystem=N'CmdExec', 
        @command=N'', 
        @database_name=N'master', 
        @output_file_name=N'', 
        @flags=0

EXEC msdb.dbo.sp_update_job @job_name=@JobName, 
        @enabled=1, 
        @start_step_id=1, 
        @notify_level_eventlog=0, 
        @notify_level_email=2, 
        @notify_level_page=2, 
        @delete_level=0, 
        @description=N'', 
        @category_name=N'[Uncategorized (Local)]', 
        @owner_login_name=N'sa', 
        @notify_email_operator_name=N'', 
        @notify_page_operator_name=N''

EXEC msdb.dbo.sp_update_jobstep 
    @job_name=@JobName, 
    @step_id=1 , 
    @command=@Command, 
    @output_file_name=@FullOutputFilePathName

EXEC msdb.dbo.sp_start_job @JobName

SELECT distinct @JobOutcome =  SJH.run_status
FROM msdb..sysjobhistory SJH, msdb..sysjobs SJ
WHERE SJH.job_id = SJ.job_id and SJ.Name = @JobName 

WHILE (@JobOutcome != 3 AND @JobOutcome > 1)
 BEGIN
    print 'In a delay loop'
    WAITFOR DELAY '00:00:02';
    SELECT distinct @JobOutcome =  SJH.run_status
    FROM msdb..sysjobhistory SJH, msdb..sysjobs SJ
    WHERE SJH.job_id = SJ.job_id and SJ.Name = @JobName
 END

SET @JobExecutionTime = GETDATE()
SELECT @JobMessage = message FROM msdb..sysjobhistory SJH, msdb..sysjobs SJ
WHERE SJH.job_id = SJ.job_id and SJ.Name = @JobName
AND step_id = 1

IF @JobOutcome = 1
    BEGIN
    print 'Job successfull'
    Declare @BulkInsertCommand varchar(max)
    CREATE TABLE #temp (results NVARCHAR(755))
    SET @BulkInsertCommand = 

    'BULK INSERT #temp
    FROM ''' + @FullOutputFilePathName +'''
    WITH
    (
    ROWTERMINATOR = ''\n'',
    DataFileType=''widechar''
    )'

    EXEC (@BulkInsertCommand)
    Select results from #temp
    execute Test.dbo.CLR_CMDSHELL_LOGGING @JobName,@InvokedBySP,@Command,@JobExecutionTime,'Job Successfull',@JobMessage
    END
ELSE 
    BEGIN
    print 'Dynamic Job failed'
    execute Test.dbo.CLR_CMDSHELL_LOGGING @JobName,@InvokedBySP,@Command,@JobExecutionTime,'Job Failed',@JobMessage
    END
IF EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name = @JobName)
EXEC msdb.dbo.sp_delete_job @job_name=@JobName


END

Теперь я запускаю выше SP, используя следующий код -

DECLARE @cmd VARCHAR(100)
SET @cmd = 'DIR /B C:\Users\Test'
--DECLARE @dirTable TABLE (oPut VARCHAR(max))
--insert @dirTable
EXEC [dbo].CMDSHELL_ALTERNATIVE @cmd
--select * from @dirTable

Результат без вставки

введите описание изображения здесь

Проблема

Код выше без вставки работает нормально, быстро возвращает результат. Но когда оператор Insert раскомментирован, SP работает вечно.

введите здесь описание изображения enter code here

Я не могу понять, где именно блокируется. Любая альтернатива / исправление выше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...