我创建了一个 Control-M 作业来执行 python 脚本。该脚本用于在 SQL Server 上执行存储过程。存储过程会从表 A 中删除一些记录,然后为表 B 打开一个游标,然后根据游标中的信息将记录插入到表 A 中。插入将发生在表 C 和表 D 的另外两个游标上。
当我在 SQL Server Management Studio 2012 上手动运行存储过程时效果很好。例如,表 A 运行存储过程后将有 400,000 条记录。
但是,运行 control-M 作业后,表 A 将只有 390,000 条记录。该问题已通过将存储过程拆分为四部分来解决,一是从表 A 中删除记录,三是根据表 B、C 和 D 的游标返回的记录将记录插入表 A。
任何人都可以提出根本原因吗?
Python 脚本
import pyodbc as mssql
import re
import base64
def ExecuteSQL(ConnectionString, SqlQuery):
print('Executing query.')
connection = ConnectionString
connectionTest = mssql.connect(connection, autocommit=True)
cursor = connectionTest.cursor()
cursor.execute(SqlQuery)
print('Query executed.')
connectionTest.commit()
if __name__ == '__main__':
with open(
r'<path>'
r'<configfile>','r') as config:
for line in config:
if re.match('^SERVER', line):
server = line.split(':')[1].strip()
elif re.match('^DB', line):
db = line.split(':')[1].strip()
elif re.match('^UID', line):
uid_en = line.split(':')[1].strip()
uid = base64.b64decode(uid_en).decode('utf-8')
elif re.match('^PWD', line):
pwd_en = line.split(':')[1].strip()
pwd = base64.b64decode(pwd_en).decode('utf-8')
connection = 'DRIVER={ODBC Driver 11 for SQL Server};SERVER=' + server + ';DATABASE=' + db + ';UID=' + uid + ';PWD=' + pwd
sql = 'EXEC MySchema.[USP_DATA_QUALITY_CHECK]'
ExecuteSQL(connection, sql)
存储过程
USE <MyDataBase>
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE MySchema.[USP_DATA_QUALITY_CHECK]
AS
BEGIN
--Delete raw score records for entities deactivated.
DELETE FROM MySchema.RPT_RAWSCORE
WHERE EntityID NOT IN (
SELECT PropertyID FROM MySchema.STG_PROPERTY
)
AND EntityType = 1
DELETE FROM MySchema.RPT_RAWSCORE
WHERE EntityID NOT IN (
SELECT AvailabilityID FROM MySchema.STG_AVAILABILITY
)
AND EntityType = 5
DELETE FROM MySchema.RPT_RAWSCORE
WHERE EntityID NOT IN (
SELECT ListingID FROM MySchema.STG_LISTING
)
AND EntityType = 6
--Delete raw score records that need to redo data quality check.
DELETE FROM MySchema.RPT_RAWSCORE
WHERE EntityID IN (
SELECT PropertyID FROM MySchema.STG_PROPERTY WHERE SkipDQ = 0
)
AND EntityType = 1
DELETE FROM MySchema.RPT_RAWSCORE
WHERE EntityID IN (
SELECT AvailabilityID FROM MySchema.STG_AVAILABILITY WHERE SkipDQ = 0
)
AND EntityType = 5
DELETE FROM MySchema.RPT_RAWSCORE
WHERE EntityID IN (
SELECT ListingID FROM MySchema.STG_LISTING WHERE SkipDQ = 0
)
AND EntityType = 6
UPDATE MySchema.RPT_RAWSCORE
SET DateKey = CONVERT(INT,CONVERT(VARCHAR, GETDATE(), 112))
DECLARE @Entity nvarchar(256), @DateKey INT, @market INT
DECLARE @getEntityID CURSOR
SELECT @DateKey=CONVERT(INT,CONVERT(VARCHAR, GETDATE(), 112))
SET @getEntityID = CURSOR FOR
SELECT PropertyID FROM MySchema.STG_PROPERTY WHERE SkipDQ = 0
OPEN @getEntityID
FETCH NEXT
FROM @getEntityID INTO @Entity
WHILE @@FETCH_STATUS = 0
BEGIN
exec MySchema.[USP_Completeness_Check] @DateKey,@Entity,@entityID=1
exec MySchema.[USP_Accuracy_Check] @DateKey,@Entity,@entityID=1
FETCH NEXT FROM @getEntityID INTO @Entity
END
CLOSE @getEntityID;
DEALLOCATE @getEntityID;
SET @getEntityID = CURSOR FOR
SELECT AvailabilityID FROM MySchema.STG_Availability WHERE SkipDQ = 0
OPEN @getEntityID
FETCH NEXT
FROM @getEntityID INTO @Entity
WHILE @@FETCH_STATUS = 0
BEGIN
exec MySchema.[USP_Completeness_Check] @DateKey,@Entity,@entityID=5
exec MySchema.[USP_Accuracy_Check] @DateKey,@Entity,@entityID=5
FETCH NEXT FROM @getEntityID INTO @Entity
END
CLOSE @getEntityID;
DEALLOCATE @getEntityID;
SET @getEntityID = CURSOR FOR
SELECT ListingID FROM MySchema.STG_LISTING WHERE SkipDQ = 0
OPEN @getEntityID
FETCH NEXT
FROM @getEntityID INTO @Entity
WHILE @@FETCH_STATUS = 0
BEGIN
exec MySchema.[USP_Completeness_Check] @DateKey,@Entity,@entityID=6
exec MySchema.[USP_Accuracy_Check] @DateKey,@Entity,@entityID=6
FETCH NEXT FROM @getEntityID INTO @Entity
END
CLOSE @getEntityID;
DEALLOCATE @getEntityID;
END;
GO