python sqlserver2014_PYMSSQL/SQL Server 2014:用作子查询的PK列表的长度是否有限制?

我实现了一个python脚本,用这个方案将数百万个文档(由.netweb应用程序生成,所有内容都放在一个目录中)分成子文件夹:year/month/batch,因为这些文档来自的所有任务最初都被分为批处理。

我的python脚本对sqlserver2014执行查询,其中包含每个文档所需的所有数据,尤其是创建文档的月份和年份。然后它使用shutil模块来移动pdf。因此,我首先执行第一个查询以获取给定月份和年份的批次列表:queryBatches = '''SELECT DISTINCT IDBATCH

FROM [DBNAME].[dbo].[WORKS]

WHERE YEAR(DATETIMEWORK)={} AND MONTH(DATETIMEWORK)={}'''.format(year, month)

然后我表演:

^{pr2}$

根据PYMSSQL使用文档,其记录被收集到一个游标中。所以我继续说:IDWorksUpdate = []

row = cursor.fetchone()

while row:

if moveDocument(...):

IDWorksUpdate.append(row[0])

row = cursor.fetchone()

最后,当循环结束时,在IDWorksUpdate中,我将成功地将文档成功地移动到子文件夹中的所有作品包。所以,我关闭光标和连接,并实例化新的连接。

最后我表演:subquery = '('+', '.join(str(x) for x in IDWorksUpdate)+')'

query = '''UPDATE [DBNAME].[dbo].[WORKS] SET NAMEDOCUMENT = \'/{}/{}/{}/\'+NAMEDOCUMENT WHERE IDWORK IN {}'''.format(year,month,idbatch,subquery)

newConn = pymssql.connect(server='localhost', database='DBNAME')

newCursor = newConn.cursor()

try:

newCursor.execute(query)

newConn.commit()

except:

newConn.rollback()

log.write('Error on updating documents names in database of works {}/{} of batch {}'.format(year,month,idbatch))

finally:

newCursor.close()

del newCursor

newConn.close()

今天早上,我看到只有几个批次的updatequery在数据库中执行失败,即使文档被正确地移到了子目录中。

该批处理有55000多个文档要移动,所以可能是IDWorksUpdate溢出,这有助于错误地创建最终更新查询?我以为55000不是一个很大的整数列表。问题是在PYMSSQL中,我们不能一次有多个连接/游标到同一个数据库,所以我不能在移动相应文件时更新记录。所以我想创建一个文档被正确移动的作品的pk列表,最后用一个新的连接/光标更新它们。会发生什么事?我做错了吗?在

更新

我刚刚编写了一个简单的脚本来重现将要执行的查询以更新记录,这是我从SQL Server得到的错误:The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.

以下是查询:UPDATE [DBNAME].[dbo].[WORKS] SET NAMEDOCUMENT = '/2016/12/1484/'+NAMEDOCUMENT WHERE IDWORK IN (list of 55157 PKs)

事实上,这个表非常大(大约有1400万条记录)。但是我需要这个PKs列表,因为只有文档被正确处理和移动的任务才能被更新。我不能简单地跑:UPDATE [DBNAME].[dbo].[WORKS] SET NAMEDOCUMENT = '/2016/12/1484/'+NAMEDOCUMENT WHERE YEAR(DATETIMEWORK)=2016 and

MONTH(DATETIMEWORK)=12 and IDBATCH=1484

这是因为我们的服务器受到了加密锁的攻击,我必须只处理和移动仍然存在的文档,等待其他文档被释放。

我应该把这些字符串分成子列表吗?怎样?在

更新2

似乎以下是一个解决方案:我将pk列表分成10000个块(一个完全实验性的数字),然后执行尽可能多的查询,每个块都有一个块作为子查询。在def updateDB(listID, y, m, b, log):

newConn = pymssql.connect(server='localhost', database='DBNAME')

newCursor = newConn.cursor()

if len(listID) <= 10000:

subquery = '('+', '.join(str(x) for x in listID)+')'

query = '''UPDATE [DBNAME].[dbo].[WORKS] SET NAMEDOCUMENT= \'/{}/{}/{}/\'+NAMEDOCUMENT WHERE IDWORKIN {}'''.format(y,m,b,subquery)

try:

newCursor.execute(query)

newConn.commit()

except:

newConn.rollback()

log.write('...')

log.write('\n\n')

finally:

newCursor.close()

del newCursor

newConn.close()

else:

chunksPK = [listID[i:i + 10000] for i in xrange(0, len(listID), 10000)]

for sublistPK in chunksPK:

subquery = '('+', '.join(str(x) for x in sublistPK)+')'

query = '''UPDATE [DBNAME].[dbo].[WORKS] SET NAMEDOCUMENT= \'/{}/{}/{}/\'+NAMEDOCUMENT WHERE IDWORK IN {}'''.format(y,m,b,subquery)

try:

newCursor.execute(query)

newConn.commit()

except:

newConn.rollback()

log.write('Could not execute partial {}'.format(query))

log.write('\n\n')

newCursor.close()

del newCursor

newConn.close()

这是一个好的/安全的解决方案吗?在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值