自动化大型 SQL 查询并将结果导出到 csv 格式的文件中?

问题描述 投票:0回答:1

我获得了一个大型 SQL 查询,该查询本质上是从多个不同的表和 dbo 中获取结果。该查询涉及 if 语句、变量和临时表。我正在尝试找出在 Microsoft SQL Server Management Studio 中自动运行此查询的最简单方法,然后将表的结果导出到带标题的格式化 CSV。

我一开始尝试让 powershell 为我运行这个查询,但由于数据库不使用 Windows 身份验证,我不断遇到权限问题,从网络上的文件中获取查询,使用 SQL 服务器进行身份验证,然后写入网络上的某个位置,因为我只指定了数据库凭据(它不会写入,因为数据库凭据在网络上没有权限),并且我找不到如何指定用于保存/写入的凭据运行查询。我的一个想法是只向数据库中的特定域服务帐户授予权限并以这种方式进行身份验证,但我还没有尝试该路线。

遇到凭据错误后,我决定研究其他选项。我开始摆弄 Python,我可以编写一个简单的 SQL 查询并让它执行我需要的操作,它将向数据库进行身份验证,打开文件并运行查询,然后将结果导出到 csv 。我以为一切都很好,直到我将文件更改为提供的 SQL 查询,然后遇到了一些问题。我的第一个问题是“NoneType”无法迭代的问题,我相信我通过将查询分解为由分号指定的单独语句并让它通过 for 循环运行来解决这个问题,但这也不起作用。我收到有关变量无法转换为字符串或类似内容的错误。在“研究”这个问题(谷歌)之后,有人提到只需去掉分号,这修复了该错误,但我后来意识到它破坏了我的Python代码,因为我不再能够一次指定一个语句。因此,目前我合并了多个不同的代码,这些代码本质上做类似的事情,但我无法将正确的部分组合在一起来完成这项工作。

这是我目前拥有的内容,请注意,当我试图找出如何实现这项工作时,其中很多内容都被注释掉了:

connectionString = odbc.connect(
    'Driver={ODBC Driver 17 for SQL Server};'
    'Server=SERVER;'
    'Database=DB;'
    'UID=USER;'
    'PWD=PASSWORD;'
)



# Open and read the query file as a single buffer
fd = open('largeQuery.sql', 'r')
# Saves query file in sqlFile variable
sqlFile = fd.read()
fd.close()

# all SQL commands from query (split on ';')
#sqlCommands = filter(None, sqlFile.split(';'))

# Execute every command from the query file
#for command in sqlCommands:
    # This will skip and report errors
    # For example, if the tables do not yet exist, this will skip over
    # the DROP TABLE commands
    #try:
        # Executes each command from query file that has been filtered by ;
        #connectionString.execute(command)
    
    #except Exception as inst:
        #print("Command skipped: ", inst)

#query = pd.read_sql_query(sqlFile, connectionString)

# Read the sql file and execute the query
#with open('largeQuery.sql', 'r') as query:
    #DF = pd.read_sql_query(query.read(),connectionString)

#DF = pd.DataFrame(query)

outname = 'Data.csv'
outdir = './dir'
if not os.path.exists(outdir):
    os.mkdir(outdir)

fullname = os.path.join(outdir, outname)   

# Outputs Query results to CSV located in file path location
#DF.to_csv(fullname) #+ datetime.now().strftime('%m/%d/%Y') + '.csv', index = False)

connectionString.close()

我还意识到,当我使用 for 循环并通过将其分解为分号来过滤每个语句时,我不知道如何在查询完全执行后从查询中获取结果。我觉得我真的很接近解决这个问题,但我完全没有 Python 经验,也几乎没有像我提供的那样的大型 SQL 查询经验。任何信息都会有所帮助,例如我是否走在正确的道路上或使用正确的工具来完成工作?!

python sql sql-server powershell
1个回答
0
投票

感谢所有评论,我综合了它们来找出适合我的场景的最佳路线:

我没有直接从文件中提取查询,而是将其创建为数据库中的存储过程。然后使用 PS 中的 Invoke-SQL 命令运行引用该存储过程的 EXEC 命令,然后使用 Export-Csv 命令将其输出到 csv。然后我在数据库服务器上的任务计划程序中创建了一个任务来每天运行这个脚本。这样做的缺点是,我经常必须进入脚本并手动更新变量,但这比每天手动执行此操作要容易得多。

这是供未来观察者使用的 PS 调用命令:

Invoke-Sqlcmd -ServerInstance $Server -数据库 $DB -用户名 $用户名 -密码 $密码 -查询 $Query | Export-Csv "C:\TEMP\queryOutput.csv" -Force -Delimiter "," -NoTypeInformation

© www.soinside.com 2019 - 2024. All rights reserved.