【发布时间】:2018-02-08 19:05:54
【问题描述】:
我有一个想要概括的存储 SQL 过程。这涉及将表名称、开始时间和结束时间作为变量传递,因此不必每次都编辑过程。我正在尝试使用基本的 python 变量来提示用户。 (Start = int(input("输入开始时间:")) 我只是还没有找到一个简单的方法来做到这一点。我已经使用了“执行 sp_execute_external_scripts”,并且一直在查看 Pyodbc 是否是正确的工具,但到目前为止没有任何效果,而且我没有完全理解用于创建包装器的 MS 文档/教程。那么提示用户输入可以作为变量注入过程的最简单方法是什么?我觉得我在这里遗漏了一些非常简单的东西。
在这里阅读 cmets 后,我的原始方法过于宽泛,需要使用 dynamicsql,我并不自动反对,但为单个表创建过程似乎更安全。所以我只需要将 Start、End 和 ChunkSize 作为整数变量推送到过程中。
已解决:我通过使用 pyodbc 编写一个小型 python 程序得到了预期的结果。感谢您的帮助和温柔地摆脱我最初的幼稚想法。
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=CROWN;'
'Database=ControlInformation;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
Start = int(input("Enter Start Time: "))
End = int(input("Enter End Time: "))
ChunkSize = int(input("Enter # of files to delete at once: "))
cursor.execute('exec PurgeCurrencyExchangeRates @start = %d, @end = %d,
@ChunkSize = %d' %(Start, End, ChunkSize))
cursor.commit(),
connection.close()
SQL 存储过程
CREATE PROCEDURE UserInput
@r int = 1,
@Start bigint = 0,
@End bigint = 0,
@TableName varchar(40) = 'CurrencyExchangeRates',
@ChunkSize int = 10000,
@ColumnName varchar(40) = 'Timestamp'
AS
BEGIN
SET NOCOUNT ON;
while @r > 0
delete top(@ChunkSize)
ControlInformation.dbo.@TableName
where @ColumnName > @Start and @ColumnName < @End
set @r = @@ROWCOUNT
【问题讨论】:
-
为什么要创建一个通用的“从表 x 中删除所有数据”过程?您不能参数化表或列名,因此这需要动态 sql。但是又一次……为什么???这有点像在编程语言中创建一个通用的删除方法,您必须传入对象名称。
-
动态传入表名表明您违反了关系数据库设计的常规规则。这应该是单个表中对数据进行分区的列。
-
目的不是从表 X 中删除所有数据。我正在尝试删除两个日期范围之间的大量行。此外,我将其分块是因为一次删除的数据太多,并且会中断我们业务在数据库上运行的其他进程。
-
我理解的分块部分。但是您正在制作一个可以从任何表中删除数据的过程。这表明您要么试图使其过于通用,要么您的架构被非规范化(或两者兼而有之)。
-
好的@SeanLange,我将稍微改变我尝试解决此问题的方式。我应该为每个要删除的表创建一个过程,而不是过度概括吗? (摆脱 TableName 和 ColumnName)这很容易做到,但我仍然有将 Start、End 和 ChunkSize 作为变量而不是静态参数推送的潜在问题。用户输入是这里的主要目标。
标签: sql sql-server stored-procedures pyodbc