下面是python语句组。我正在使用python动态构建sql语句。生成的SELECT
语句随后用作bcp中的queryout
语句。
我的问题是查询本身太大,BCP无法操作它我已确认BCP使用:
BCP "Select * from <<DATABASE.dbo.TABLE>>" queryout "D:\data\test.csv" -t^ -r '0x0A'
-U <<USER>> -P <<PASSWORD>> -S "LIVE" -c -C65001
但是,如果select语句返回大量数据,则该语句将失败。我该怎么对付该表很大(超过100M条记录),我只想使用动态SQL将其从远程服务器导出到本地表。
python脚本:
def getRoster(self):
self.conn = pyodbc.connect(self.ConnStr)
sql = r'SELECT * FROM <<DB>>.dbo.TableConfiguration'
self.roster = pd.read_sql(sql,self.conn)
def GenerateSQL(self, table):
exportsql = 'select '
columnsql = """select
'CASE WHEN ISNULL('+COLUMN_NAME+', '''') = '''' THEN '''' ELSE '+COLUMN_NAME+' END AS '+UPPER(COLUMN_NAME)
from <<DB>>.INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = '%s'
order by ORDINAL_POSITION""" % table.tablename
self.conn = pyodbc.connect(self.ConnStr)
cursor = self.conn.cursor()
cursor.execute(columnsql)
exportsql += ', '.join([field[0] for field in cursor])
exportsql += ' from {}.dbo.{}'.format(table.dbname, table.tablename)
exportsql += ' {}'.format(table.Clause)
return (exportsql)
def ExportTables(self):
now = datetime.now()
self.getRoster()
for row in self.roster.itertuples():
SQL = self.GenerateSQL(row)
self.filename = '{}_{}.csv'.format(row.tablename, now.strftime("%Y-%m-%d"))
command = 'BCP \"{}\" queryout \"{}\" -t|| -U "<<USER>>" -P <<PASSWORD>> -S "LIVE" -T -r 0x0a -c -C65001'.format(SQL, os.path.join(self.path, self.filename))
print (command)
subprocess.run(command)
当用
SELECT 'test'
测试bcp时,它恢复正常工作但是当生成sql时,sql在SMSS中工作,但是在bcp中,错误是:SQLState = 28000, NativeError = 18452
Error = [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Login failed. The login is from an untrusted domain and cannot be used with Windows authentic
ation.
最佳答案
从bcp命令行中删除-t参数并使用sql server身份验证。
bcp Utility - T
当bcp实用工具使用受信任的
使用集成安全性连接,使用-t选项(可信
连接)而不是用户名和密码组合什么时候?
bcp实用程序正在连接到sql数据库或sql数据仓库,
使用Windows身份验证或Azure活动目录身份验证
不支持。使用-u和-p选项。