如何在 Python 中使用表值参数访问 SQL Server 2008 存储过程
Posted
技术标签:
【中文标题】如何在 Python 中使用表值参数访问 SQL Server 2008 存储过程【英文标题】:How to access a SQL Server 2008 stored procedure with a table valued parameter in Python 【发布时间】:2011-08-09 19:06:19 【问题描述】:我正在寻找一种方法来获取结果集并使用它来查找驻留在 SQL Server 2008 中的表中的记录,而无需一次翻阅记录。用于查找记录的结果集可能数以十万计。到目前为止,我正在使用 sqlite3 在内存中创建一个表,然后尝试将该表提供给一个采用表值参数的存储过程。 SQL Server 端的工作已经完成,创建了用户定义的类型,存在接受表值参数的测试过程,我已经通过 TSQL 对其进行了测试,它似乎工作得很好。在 Python 中,通过 sqlite3 创建了一个简单的内存表。现在要注意了,我找到的唯一一个使用表值参数访问存储过程的文档使用 ADO.Net 和 VB,在 Python 中没有。不幸的是,我的程序员还不够翻译。有没有人使用带有表值参数的 SQL Server 存储过程?我应该研究另一种方法吗?
这里有一些链接: 表值参数的体面解释以及如何在 SQL 中设置它们并在 .Net 中使用
http://www.sqlteam.com/article/sql-server-2008-table-valued-parameters
http://msdn.microsoft.com/en-us/library/bb675163.aspx#Y2142
在Python中使用ADO的解释——几乎是我需要的,只需要结构化的参数类型。 http://www.mayukhbose.com/python/ado/ado-command-3.php
我的简单代码
--TSQL to create type on SQL database
create Type PropIDList as Table
(Prop_Id BigInt primary key)
--TSQL to create stored procedure on SQL database. Note reference to
create procedure PropIDListTest @PIDList PropIDList READONLY
as
SET NOCOUNT ON
select * from
@PIDList p
SET NOCOUNT OFF
--TSQL to test objects.
--Declare variable as user defined type (table that has prop_id)
declare @pidlist as propidlist
--Populate variable
insert into @pidlist(prop_id)
values(1000)
insert into @pidlist(prop_id)
values(2000)
--Pass table variable to stored procedure
exec PropIDListTest @pidlist
现在是困难的部分——Python。
这是创建内存表的代码
import getopt, sys, string, os, tempfile, shutil
import _winreg,win32api, win32con
from win32com.client import Dispatch
from adoconstants import *
import sqlite3
conn1 = sqlite3.connect(':memory:')
c = conn1.cursor()
# Create table
c.execute('''create table PropList
(PropID bigint)''')
# Insert a row of data
c.execute("""insert into PropList
values (37921019)""")
# Save (commit) the changes
conn1.commit()
c.execute('select * from PropList order by propID')
# lets print out what we have to make sure it works
for row in c:
print row
好的,我尝试通过 Python 进行连接
conn = Dispatch('ADODB.Connection')
conn.ConnectionString = "Provider=sqloledb.1; Data Source=nt38; Integrated Security = SSPI;database=pubs"
conn.Open()
cmd = Dispatch('ADODB.Command')
cmd.ActiveConnection = conn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "PropIDListTest @pidlist = ?"
param1 = cmd.CreateParameter('@PIDList', adUserDefined) # I “think” the parameter type is the key and yes it is most likely wrong here.
cmd.Parameters.Append(param1)
cmd.Parameters.Value = conn1 # Yeah, this is probably wrong as well
(rs, status) = cmd.Execute()
while not rs.EOF:
OutputName = rs.Fields("Prop_ID").Value.strip().upper()
print OutputName
rs.MoveNext()
rs.Close()
rs = None
conn.Close()
conn = None
# We can also close the cursor if we are done with it
c.close()
conn1.close()
【问题讨论】:
为什么要在 Python 中这样做? IronPython 是一种选择吗?还是您仅限于 CPython? Python 得到我们的主要供应商 (ESRI) 的支持,他们提供了一个 Python 插件,允许我们编写空间分析和地图制作脚本。我不确定 arcpy 是否可以在 IronPython 中工作。如果是这样,那肯定是一种选择。我将查看 ESRI 以获取 IronPython 的支持。 ESRI 不支持 IronPython。 一年过去了,仍然没有答案。也许我应该提供赏金。 【参考方案1】:我以前从 ADO.NET 编写过 TVP。 这是我感兴趣的关于经典 ADO 中 TVP 的问题,sql server - Classic ADO and Table-Valued Parameters in Stored Procedure - Stack Overflow。它没有给出直接的答案,而是给出了替代方案。
XML 的选项更简单,你可能已经考虑过了;这将需要更多的服务器端处理。 这是用于 TVP 的低级 ODBC 编程的 msdn 链接。 Table-Valued Parameters (ODBC)。如果您可以切换到 ODBC,这是最接近的答案。 您可以将 csv 字符串传递给 nvarchar(max),然后将其传递给 CLR SplitString function,该字符串速度很快,但具有我不同意的默认行为。请在此处发回有效或无效的内容。
【讨论】:
以上是关于如何在 Python 中使用表值参数访问 SQL Server 2008 存储过程的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 C# 和 SQL 将表值参数传递给用户定义的数据表
如何使用 JDBC 将表值参数(类数组参数)传递给 Microsoft SQL Server 2008 R2 中的存储过程? [复制]