我编写了一个SQL脚本来将名称映射到报告名称。我在我的本地SQL server 2012机器上验证了。它运作良好。但是,当我在服务器上运行时,我收到了错误
Msg 537,Level 16,State 3,Line 40
传递给LEFT或SUBSTRING函数的长度参数无效。
我也尝试直接在远程服务器上运行“select”部分,结果也是正确的。 我不明白为什么会出错。有什么想法吗? (注意:我在错误行中添加“error here - >”)
DECLARE @jobTable TABLE
(
job_name nvarchar(max),
report_name nvarchar(max),
event_type nvarchar(max),
description nvarchar(max),
last_run_date int,
last_run_time int
)
declare
@job_name uniqueidentifier,
@report_name nvarchar(max),
@event_type nvarchar(max),
@description nvarchar(max),
@last_run_date int,
@last_run_time int,
@last_run_dur int
/************** alert ********/
declare getId_alertjob_cursor cursor for (
SELECT
[jobs].[name] job_name,
alertFeed.relativePath report_name,
CONVERT(nvarchar(max), SUBSTRING([steps].[command], CHARINDEX(' @EventType=''', [steps].[command], 0) + LEN(' @EventType='''), CHARINDEX('''', [steps].[command], CHARINDEX(' @EventType=''', [steps].[command]) + LEN(' @EventType=''')) - CHARINDEX(' @EventType=''', [steps].[command], 0) - LEN(' @EventType=''')), 0) event_type,
[steps].[last_run_date] last_date,
[steps].[last_run_time] last_time,
[steps].[last_run_duration] last_dur
FROM [msdb].[dbo].[sysjobs] [jobs] INNER JOIN [msdb].[dbo].[sysjobsteps] [steps] ON [jobs].[job_id] = [steps].[job_id], ReportingService_4c0ed75e1e8c4e50acbf853867f071f3_Alerting.dbo.AlertDefinition [alertDef], ReportingService_4c0ed75e1e8c4e50acbf853867f071f3_Alerting.dbo.Feed [alertFeed]
WITH (NOLOCK)
WHERE [jobs].[name] <> 'syspolicy_purge_history'
and alertDef.scheduleid = CONVERT(nvarchar(max), SUBSTRING([steps].[command], CHARINDEX(' @EventData=''', [steps].[command], 0) + LEN(' @EventData='''), CHARINDEX('''', [steps].[command], CHARINDEX(' @EventData=''', [steps].[command]) + LEN(' @EventData=''')) - CHARINDEX(' @EventData=''', [steps].[command], 0) - LEN(' @EventData=''')), 0)
and alertDef.FeedId = alertFeed.FeedId
);
open getId_alertjob_cursor
error here--> fetch next from getId_alertjob_cursor INTO @job_name, @report_name, @event_type, @last_run_date, @last_run_time, @last_run_dur
while @@FETCH_STATUS = 0
BEGIN
-- INSERT INTO @jobTable VALUES (@job_name, @report_name, @event_type,'Alert',0,0);
-- ,@last_run_date,@last_run_time);
fetch next from getId_alertjob_cursor INTO @job_name, @report_name, @event_type, @last_run_date, @last_run_time,@last_run_dur
END
close getId_alertjob_cursor
deallocate getId_alertjob_cursor
答案 0 :(得分:1)
我怀疑是因为有些作业的步骤不包含短语@EventType='
,这会导致子字符串失败。
添加快速签入以确保它首先存在,如下所示:
Case
When CHARINDEX(' @EventType=''', [steps].[command]) > 0 Then
CONVERT(nvarchar(max), SUBSTRING([steps].[command], CHARINDEX(' @EventType=''', [steps].[command], 0) + LEN(' @EventType='''), CHARINDEX('''', [steps].[command], CHARINDEX(' @EventType=''', [steps].[command]) + LEN(' @EventType=''')) - CHARINDEX(' @EventType=''', [steps].[command], 0) - LEN(' @EventType=''')), 0)
Else ''
End as [EventType]
注意到你在WHERE子句中有这个:
and alertDef.scheduleid = CONVERT(nvarchar(max), SUBSTRING([steps].[command], CHARINDEX(' @EventData=''', [steps].[command], 0) + LEN(' @EventData='''), CHARINDEX('''', [steps].[command], CHARINDEX(' @EventData=''', [steps].[command]) + LEN(' @EventData=''')) - CHARINDEX(' @EventData=''', [steps].[command], 0) - LEN(' @EventData=''')), 0)
您还应该添加一项检查,以查看command
字段是否包含@EventData
也许如果你试图解释你想要实现什么,可能会发布一个更好的查询。
答案 1 :(得分:0)
首先,我想提一下在这种情况下不需要使用游标。即您的查询可以简化为以下内容:
DECLARE @jobTable TABLE
(
job_name SYSNAME
, report_name SYSNAME
, event_type NVARCHAR(1000)
, [description] NVARCHAR(2000)
, last_run_date INT
, last_run_time INT
)
INSERT INTO @jobTable
(
job_name
, report_name
, event_type
, last_run_date
, last_run_time
)
SELECT
d.job_name
, report_name = alertFeed.relativePath
, d.event_type
, d.last_date
, d.last_time
FROM (
SELECT
job_name = j.[name]
, event_type = CASE WHEN CHARINDEX(' @EventType=''', s.[command]) > 0
THEN CONVERT(NVARCHAR(MAX), SUBSTRING(s.[command], CHARINDEX(' @EventType=''', s.[command], 0) + LEN(' @EventType='''), CHARINDEX('''', s.[command], CHARINDEX(' @EventType=''', s.[command]) + LEN(' @EventType=''')) - CHARINDEX(' @EventType=''', s.[command], 0) - LEN(' @EventType=''')), 0)
ELSE ''
END
, last_date = s.[last_run_date]
, last_time = s.[last_run_time]
FROM [msdb].dbo.sysjobs j WITH (NOLOCK)
JOIN [msdb].dbo.sysjobsteps s WITH (NOLOCK) ON j.job_id = s.job_id
WHERE j.[name] != 'syspolicy_purge_history'
) d
JOIN [ReportingService_4c0ed75e1e8c4e50acbf853867f071f3_Alerting].dbo.AlertDefinition [alertDef] ON alertDef.scheduleid = event_type
JOIN [ReportingService_4c0ed75e1e8c4e50acbf853867f071f3_Alerting].dbo.Feed [alertFeed] ON alertDef.FeedId = alertFeed.FeedId
另外,我对数据库[ReportingService _..._ Alerting]感到不安。如果它位于执行任务的同一服务器上,则可能拒绝使用该数据库。