使用Python将变量插入SQL存储过程的最简单方法是什么?

时间:2018-02-08 19:05:54

标签: sql sql-server stored-procedures pyodbc

我有一个存储的SQL过程,我想概括一下。这涉及将表名,开始时间和结束时间作为变量传递,因此不必每次都编辑该过程。我正在尝试使用基本的python变量来提示用户。 (Start = int(输入(“输入开始时间:”)) 我还没有找到一个简单的方法来做到这一点。我已经使用'执行sp_execute_external_scripts'并且已经看到Pyodbc是否是正确的工具,但到目前为止没有任何工作,我没有完全理解用于创建包装器的MS文档/教程。那么提示用户输入可以作为变量注入过程的最简单方法是什么?我觉得我在这里缺少一些非常简单的东西。

在这里阅读评论时,我的原始方法过于宽泛,需要使用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

3 个答案:

答案 0 :(得分:0)

也许你需要在python:

Start = int(input("Enter Start Time: "))
sql = 'exec UserInput @start =?'
cursor.execute(sql, Start)
cursor.commit()

答案 1 :(得分:0)

存储过程应该类似于:

use CurrencyExchangeRates
go
CREATE PROCEDURE PurgeCurrencyExchangeRates 
@Start bigint = 0, 
@End bigint = 0,
@ChunkSize int = 10000
AS
BEGIN
    SET NOCOUNT ON;
    declare @r int = 1;


    while @r > 0
    begin
        delete top(@ChunkSize)
            from dbo.CurrencyExchangeRates
            where [Timestamp] >= @Start and [Timestamp] < @End

        set @r = @@ROWCOUNT
    end

end

答案 2 :(得分:0)

如果你真的想让表名动态,那么你需要使用动态SQL ,如下所示:

ALTER PROCEDURE DeleteFrom 
    @tableName sysname ='Table0'
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @sql nvarchar(4000);
    SET @sql = N'DELETE TOP (1) FROM ' + QUOTENAME(@tableName);
    EXEC(@sql);
END