我正在尝试从一台服务器向另一台服务器插入数据(使用存储过程)。这是服务器架构的限制,我不得不解决它。
话虽这么说,我在serverA
上有一个存储过程,它通常可以连接到serverB
并且可以正常执行操作,因为这两个服务器是链接的。
问题是pymssql
使用了事务,因此我不断收到此错误:
File "pymssql.pyx", line 465, in pymssql.Cursor.execute (pymssql.c:7190)
pymssql.OperationalError:
(7391, b'The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "ServerB" was unable to begin a distributed transaction. DB-Lib error message 20018, severity 16: General SQL Server error: Check messages from the SQL Server.)
当我在服务器上用BEGIN TRAN
作为存储过程的前言时,我看到同样的错误,所以我得出的结论是因为pymssql
使用了事务,我可能无法进行交叉-server分布式事务。
以下是代码:
def databasedata(start, end):
startday = datetime.datetime.strptime(str(start), '%m/%d/%Y')
endday = datetime.datetime.strptime(str(end), '%m/%d/%Y')
conn = pymssql.connect( user=os.getenv('SQLUSER'),
password=os.getenv('SQLP'),
server='serverA',
database=os.getenv('SQLDB'))
cursor = conn.cursor()
cursor.execute(' select day from dbo.valid_days '
'where day between %s and %s',
(startday, endday)
)
days = cursor.fetchall()
for day in days:
date = ('%s-%s-%s' % day[0].timetuple()[:3])
cursor.execute('exec [hooper].[dbo].[cross_server_generation] %s', date)
conn.commit()
if __name__ == '__main__':
(firstday, secondday) = (sys.argv[1], sys.argv[2])
databasedata(firstday, secondday)
答案 0 :(得分:0)
我没有使用pymssql,而是选择通过subprocess
将其作为子程序运行。
import subprocess
def databasedata(start, end):
startday = datetime.datetime.strptime(str(start), '%m/%d/%Y')
endday = datetime.datetime.strptime(str(end), '%m/%d/%Y')
conn = pymssql.connect( user=os.getenv('SQLUSER'),
password=os.getenv('SQLP'),
server='serverA',
database=os.getenv('SQLDB'))
cursor = conn.cursor()
cursor.execute(' select day from dbo.valid_days '
'where day between %s and %s',
(startday, endday)
)
days = cursor.fetchall()
cursor.close()
for day in days:
date = ('%s-%s-%s' % day[0].timetuple()[:3])
statement = 'exec [hooper].[dbo].[cross_server_generation] \'%s\'' % date
subprocess.call(["sqlcmd", "-S", sqlserver, "-Q", statement])
if __name__ == '__main__':
(firstday, secondday) = (sys.argv[1], sys.argv[2])
databasedata(firstday, secondday)