Django调用存储过程,事务未提交或执行失败

时间:2019-06-14 12:23:03

标签: python sql-server django

我有此代码基于django manage命令运行。它有助于使用临时表和熊猫库加载一堆数据

def MergeAce(table=None,user=1,db_instance=None):
    if db_instance:
        db = db_instance
    else:
        return False

    with connections[db].cursor() as cursor:
        result = cursor.execute(f"spMergeAce {user} , '{table}'")
        cursor.commit()
    return result

我知道我没有正确调用参数,并且当前 callproc 不适用于 pyobdc

但是,似乎某些代码在运行,但有些则没有。这是其调用过程的示例。请使用合并语句来记录它。

-- =============================================
-- Author:      <Pickle,Travis>
-- Create date: <June 13 2019>
-- Description: <Create and update ace from temp table>
-- =============================================
ALTER PROCEDURE [dbo].[spMergeAce]
    -- Add the parameters for the stored procedure here
    @user int = 1,
    @table varchar(50)

AS
BEGIN
    SET NOCOUNT ON;

    declare @query nvarchar(max) = ''
    -- ,@user int = 1, @table varchar(50) = 'cat'



    set @query = N'
          with cte as(
        SELECT aclid, hash, ConfigLine,  RN = ROW_NUMBER()
         OVER(PARTITION BY aclid, hash, ConfigLine ORDER BY aclid, hash, ConfigLine)
           FROM [dbo].['+ @table + '] new) delete from cte where RN > 1;


    MERGE [dbo].[ACE] AS TARGET
    USING [dbo].['+ @table + '] AS SOURCE 
    ON (TARGET.aclid = SOURCE.aclid and TARGET.hash = SOURCE.hash and TARGET.configline = SOURCE.configline ) 
    WHEN MATCHED
        AND (TARGET.[hitcount] <> SOURCE.[hitcount]
        OR TARGET.[line] <> SOURCE.[Line]
        OR TARGET.[line] is NULL
        OR TARGET.[hitcount] is NULL
        )
        THEN UPDATE SET
            TARGET.[hitcount] = SOURCE.[hitcount],
            TARGET.[UpdateDate] = getdate(),
            TARGET.[Source] = SOURCE.[Source] ,
            TARGET.[Service] = SOURCE.[Service],
            TARGET.[Protocol] = SOURCE.[Protocol],
            TARGET.[Destination] = SOURCE.[Destination],
            TARGET.[line] = SOURCE.[Line] ,
            TARGET.[Inactive] = 0,
            TARGET.[InactiveDate] = NULL
    WHEN NOT MATCHED BY TARGET 
        THEN
            INSERT (
                [ACLid],
                [Hash],
                [Source],
                [Destination],
                [Service],
                [Protocol],
                [ConfigLine],
                [CreateDate],
                [UpdateDate],
                [CreateUser],
                [UpdateUser],
                [line],
                [hitcount],
                [Inactive])
            VALUES (
                SOURCE.[aclid],
                SOURCE.[hash],
                SOURCE.[Source],
                SOURCE.[Destination],
                SOURCE.[Service],
                SOURCE.[Protocol],
                SOURCE.[ConfigLine],
                getdate(),
                getdate(),
                ' + cast(@user as varchar(50)) + ' ,
                  ' + cast(@user as varchar(50)) + ',
                SOURCE.[Line],
                SOURCE.[hitcount],
                0)          

    OUTPUT $action, 
    INSERTED.[aclid] AS SourceAclId, 
    INSERTED.[ConfigLine] AS SourceConfigLine, 
    INSERTED.[Hash] AS SourceHash, 
    INSERTED.[Protocol] AS SourceProtocol,
    INSERTED.[Service] AS SourceService,
    INSERTED.[Source] AS SourceSourceNets,
    INSERTED.[Destination] AS SourceDestinationNets,
    INSERTED.[Inactive] as SourceInactive; 


    UPDATE TARGET
    set
        TARGET.updateuser = ' + cast(@user as varchar(50)) + ',
        TARGET.updatedate = getdate(),
        TARGET.[Inactive] = 1,
        TARGET.[InactiveDate] = getdate()
    from [dbo].[ACE] AS TARGET
    left join [dbo].['+ @table + '] AS SOURCE on TARGET.aclid = SOURCE.aclid and TARGET.hash = SOURCE.hash and TARGET.configline = SOURCE.configline
    where SOURCE.id is null AND TARGET.[Inactive] <> 1 AND TARGET.aclid in (
        SELECT distinct ace2.aclid from ace ace2 join acl on acl.id = ace2.aclid where acl.zoneid in (SELECT distinct zoneid from [dbo].['+ @table + '])); 

    drop table [dbo].['+ @table + '];
    '


    exec sp_executesql @query
    COMMIT
END

此外,如果我更新存储过程中的变量,则它可以在SSMS中工作。不知道django / pyobdc是调用存储过程的原因还是我的存储过程。

1 个答案:

答案 0 :(得分:0)

所以我错过了几件事。但这是解决问题的方法。 EXEC已添加


def MergeAcl(table=None,user=1,db_instance=None):
    if db_instance:
        db = db_instance
    else:
        return False
    with connections[db].cursor() as cursor:
        try:
            cursor.execute(f"EXEC [dbo].spMergeAcl @user = {user}, @table = [{table}]")
        except Exception as e:
            logger.error(e)
            return False
        rows = cursor.fetchall()
        while rows:
            logger.debug(rows) # not needed, just used for debugging
            if cursor.nextset():
                rows = cursor.fetchall()
            else:
                rows = None
    return True