You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一SQL Server实例跨库执行存储过程报sys.servers找不到服务器错误

问题原因及解决方案

你的代码存在两处关键错误,导致了这个报错:

1. 错误的ODBC连接字符串

你在pyodbc.connect()里重复设置了Driver、Server、Database参数,这不符合ODBC连接规范——一个ODBC连接只能指向单个数据库(同一SQL Server实例下)。同一实例内的其他数据库,只需通过数据库名.架构名.表名的格式直接引用即可,无需在连接字符串中重复配置。

2. 错误的数据库变量拼接

你执行了ABC_database=f'{ABC_database}.dbo',之后在SQL语句中引用表时就变成了{ABC_database}.dbo.{tab},最终生成的SQL会是ABC.dbo.dbo.TABLE_NAME_HERE。SQL Server会将这种格式解析为[服务器名].[数据库名].[架构名].[表名],所以它误以为ABC是一个链接服务器,从而抛出找不到服务器的错误。


修正后的代码

import pyodbc
import logging
import json
import time

def pop_abc_insert():
    # 配置日志(添加控制台输出)
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    if not logger.handlers:
        handler = logging.StreamHandler()
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
    
    start_time = time.time()

    with open(r'upsert_config.json','r') as ts:
        config = json.load(ts)

    ABC_driver = config['ABC_layer']['ABC_driver']
    ABC_server = config['ABC_layer']['ABC_server']
    ABC_database = config['ABC_layer']['ABC_database']
    POP_database = config['POP_layer']['POP_database']

    # 修正连接字符串:只连接到同一实例下的一个数据库即可
    conn = pyodbc.connect(
        f'Driver={ABC_driver};'
        f'Server={ABC_server};'
        f'Database={ABC_database};'
        f'Trusted_Connection=yes;'
        f'MARS_Connection=Yes'
    )

    try:
        cursor = conn.cursor()
        read_table_query="""        
        SELECT table_name 
        FROM information_schema.tables
        WHERE table_name = 'TABLE_NAME_HERE'
        ORDER BY table_name asc
        """
        cursor.execute(read_table_query)  
        logger.info("Successfully connected to database")

    except Exception as e:
        logger.error("Unable to connect to database: %s", str(e))
        return

    for tables in cursor.fetchall():
        tab = tables[0]
        # 修正表引用格式:直接用 数据库名.dbo.表名
        ABC_POP_query = f"""
                            update {POP_database}.dbo.{tab} SET
                            Active_ind = 0,
                            expiry_date = GETDATE(), 
                            updated_date = GETDATE()
                            WHERE convert(varbinary,hash_key )IN (
                            SELECT convert(varbinary,T1.hash_key)
                            FROM {ABC_database}.dbo.{tab} T1 LEFT JOIN
                                {POP_database}.dbo.{tab} T2 ON convert(varbinary,T1.hash_key) = convert(varbinary,T2.hash_key)
                            WHERE convert(varbinary,T1.hash_dif) <> convert(varbinary,T2.hash_dif)
                            AND T1.Active_ind = 1
                            ) AND Active_ind = 1
                            
                            insert into {POP_database}.dbo.{tab} 
                            select * from {ABC_database}.dbo.{tab}
                            WHERE convert(varbinary,hash_key) IN (
                            SELECT convert(varbinary,T1.hash_key)
                            FROM {ABC_database}.dbo.{tab} T1 LEFT JOIN
                                {POP_database}.dbo.{tab} T2 ON convert(varbinary,T1.hash_key) = convert(varbinary,T2.hash_key)
                            WHERE convert(varbinary,T1.hash_dif) <> convert(varbinary,T2.hash_dif)
                            AND T1.Active_ind = 1)
                                                    
                            insert into {POP_database}.dbo.{tab}
                            select * from {ABC_database}.dbo.{tab} 
                            WHERE convert(varbinary, hash_key) NOT IN (
                            SELECT convert(varbinary,T2.hash_key)
                            FROM {POP_database}.dbo.{tab} T2
                            WHERE T2.Active_ind = 1)
                        """
        try:
            cursor.execute(ABC_POP_query)
            conn.commit()  # 提交事务,确保修改生效
            logger.info(f"Successfully processed table: {tab}")
        except Exception as e:
            conn.rollback()  # 出错回滚
            logger.error(f"Error processing table {tab}: %s", str(e))

    conn.close()
    logger.info(f"Process completed in {time.time() - start_time:.2f} seconds")

pop_abc_insert()

额外说明

  • 你的JSON配置文件无需修改,因为配置的服务器和数据库信息是正确的。
  • 新增了事务提交/回滚逻辑,避免出现部分更新的情况。
  • 完善了日志配置,确保能看到运行时的日志信息。

内容的提问来源于stack exchange,提问作者Forgottenluv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:07:09