【发布时间】:2017-03-22 16:59:39
【问题描述】:
我有一系列存储过程,首先执行 ETL 过程,然后将一些公式的结果加载到新表中。在该过程的最后,我有一小段代码将输出表与输入表进行比较,以确保所有记录都在那里。我已经把这一切都放到了一个 SQL 代理作业中,并安排它每天早上运行。
如果我手动运行 SQL Server 代理作业,一切正常。但是,当我让代理按计划执行作业时,比较表的代码会通知我许多记录不在最终表中。在表中大约 100 万条记录中,每天它说只有大约 2000 条不在决赛桌中。这个数字每天都在变化。
我怀疑这是权限问题,因为我有其他代理工作没有这个问题。
关于可能导致这种行为的任何想法?
编辑
这是插入数据的代码。我的数据有三种类型,两种不同的版本。我本可以将它们全部构建到一个存储过程中,但是由于过程可以更改的方式,它被拆分为每个类型/版本组合的单独存储过程。在每个存储过程结束时,都会使用存储过程的结果构建一个临时表。例如,这个临时表名为##ResultsT1Ver1,调用UpdateResultTable,父存储过程的类型和版本作为参数传入。
请注意,当我运行我的存储过程时,我会在构建临时表之前构建一个中间表。查找一条标记为未进入结果表的记录表明它在中间表中。所以我认为问题在于插入或临时表的存储。
每个单独的存储过程超过 300 行,整理它们需要更长的时间才能在此处发布。
ALTER PROCEDURE [dbo].[UpdateResultTable] @Version varchar(2), @Type varchar(15)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SQL NVARCHAR(4000);
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'Results'))
BEGIN
IF (EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('dbo.Results') AND name = 'IDX_Results_Epinum'))
BEGIN DROP INDEX [IDX_Results_Epinum] ON dbo.Results END
END
ELSE
CREATE TABLE dbo.Results
(
ResultsId [int] IDENTITY(1,1) NOT NULL,
ValType VARCHAR(10) NULL,
Epinum VARCHAR(50) NULL,
N15 DECIMAL(25,13) NULL,
G15 DECIMAL(25,13) NULL,
N16 DECIMAL(25,13) NULL,
G16 DECIMAL(25,13) NULL,
EstablishmentId VARCHAR(9) NULL,
ServiceDate datetime NULL,
ExcludedRecord VARCHAR(11) NULL,
CONSTRAINT [PK_Results] PRIMARY KEY CLUSTERED (ResultsId)
);
SET @SQL = N'
IF EXISTS (SELECT n.Epinum FROM ##Results' + @Version + @Type + N' n INNER Join dbo.Results r on r.Epinum = n.Epinum WHERE n.N' + @VERSION + ' <> r.N' + @VERSION + ' OR n.G' + @VERSION + ' <> r.G' + @VERSION + '
OR n.ValType <> r.ValType OR n.ExcludedRecord <> r.ExcludedRecord)
BEGIN
UPDATE D
SET D.N' + @VERSION + ' = S.N' + @VERSION + ',
D.G' + @VERSION + ' = S.G' + @VERSION + ',
D.ValType = S.ValType ,
D.ExcludedRecord = S.ExcludedRecord
FROM dbo.Results D
INNER JOIN ##Results' + @Version + @Type + N' S ON D.Epinum = S.Epinum
END
ELSE
BEGIN
INSERT INTO dbo.Results
SELECT
ValType,
Epinum,'
SET @SQL = @SQL + CASE WHEN @Version = '15' THEN N'N15, G15, 0.0, 0.0, ' ELSE N'0.0,0.0,N16, G16, ' END
SET @SQL = @SQL + N'
EstablishmentId ,
ServiceDate,
ExcludedRecord
FROM ##Results' + @Version + @Type + N' S
WHERE NOT EXISTS (SELECT Epinum FROM dbo.Results D WHERE S.Epinum = D.Epinum)
END'
--select @SQL
print @sql
declare @val int;
declare @printsql NVARCHAR(4000);
set @printsql = 'declare @val int;
select @val = count(*) from ##Results' +@version + @type +'; print @val;'
exec sp_executesql @printsql;
exec sp_executesql @SQL;
CREATE NONCLUSTERED INDEX [IDX_Results_Epinum] ON dbo.Results (Epinum ASC) INCLUDE (N15, G15, N16,G16)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = ON, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
END
【问题讨论】:
-
您有其他代理作业对表具有插入权限,或者至少将记录插入到同一架构中的类似表中?
-
您是从多个位置加载吗?有没有可能其中一个失败?您可以尝试的一种选择是将您自己的帐户设置为凭证/代理,并将作业步骤配置为使用您的帐户运行。看看它是否有效。
-
@scsimon 我还有另一项工作,从同一个 sourcedb 复制数据,但删除并重建最终表。有问题的作业有 6 个 sp 都插入到同一个表中。
-
@Nayak 不,我有一个独立的 sp 来处理从 sourcedb 中提取数据。我认为问题出在插入决赛桌的 sp 中。不知道在哪里,因为只有在调度程序运行作业时才会出现问题
-
可能是权限问题?通常,当您在 ssms 中运行作业时,您正在使用您的凭据。
标签: sql sql-server tsql sql-server-2012 sql-agent-job