如何在不使用事务的情况下在 pymssql 中执行跨服务器存储过程?

How can I execute a cross-server Stored Procedure in pymssql without using Transactions?

我正在尝试将数据(使用存储过程)从一台服务器插入到另一台服务器。这是服务器架构的限制,我不得不解决它。

也就是说,我在 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 使用事务,我可能无法执行跨服务器分布式事务。

代码如下:

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)

我没有使用 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)