如何逐个执行存储过程作为参数?

时间:2013-10-13 12:45:28

标签: sql stored-procedures user-defined-types

CREATE TYPE [dbo].[JNLOBJLIST] AS TABLE(
    [Journal_Master_Id] [int] NULL,
    [strTransRefNumber] [varchar](50) NULL,
    [dateGLTransDate] [date] NULL,
    [decGLTransAmount] [decimal](18, 4) NULL,
    [strGLTransRemark] [varchar](50) NULL,
    [guidCompanybranchId] [uniqueidentifier] NULL,
    [intGLAccountId] [int] NULL,
    [intFiscalYearId] [int] NULL,
    [boolGLIsDebit] [binary](1) NULL,
    [strPerson] [varchar](50) NULL,
    [inttblReferenceId] [int] NULL,
    [decGLTransAmount2] [decimal](18, 4) NULL,
    [strJournalmemo] [varchar](50) NULL)
GO

和SP:

CREATE PROCEDURE [dbo].[usp_insertGl_transtemp2] 
@LIST [dbo].JNLOBJLIST READONLY

AS
DECLARE @id int

BEGIN

INSERT INTO tbl_GL_Trans_Detailstemp
                    ( trans_ref_number
                    , GL_trans_date
                    , GL_trans_amount
                    , GL_trans_remark
                    , company_branch_id
                    , GL_Account_id
                    , fiscal_year_id
                    , IsDebit
                    , Person
                    , tbl_reference_Id)

SELECT              strTransRefNumber
                    , dateGLTransDate
                    , decGLTransAmount
                    , strGLTransRemark
                    , guidCompanybranchId
                    , intGLAccountId
                    , intFiscalYearId
                    , boolGLIsDebit
                    , strPerson
                    , inttblReferenceId FROM @LIST

SET @id = (SELECT MAX(GL_trans_id)
FROM   tbl_GL_Trans_Detailstemp)


UPDATE    tbl_Gl_account
SET GL_Balance = GL_Balance + (SELECT decGLTransAmount2 FROM @LIST)
WHERE (GL_Account_id = (SELECT intGLAccountId FROM @LIST))

DECLARE @Journal_Master_Id int
DECLARE @Trans_Id int
DECLARE @Amount decimal
DECLARE @Memo varchar(50)

SET @Journal_Master_Id=(SELECT Journal_Master_Id FROM @LIST)
SET @Trans_Id=(@id)
SET @Amount=(SELECT decGLTransAmount FROM @LIST)
SET @Memo=(SELECT strJournalmemo FROM @LIST)

INSERT INTO tbl_Journal_Details
    (Journal_Master_Id, Trans_Id, Amount, Memo)
VALUES     (@Journal_Master_Id,@Trans_Id,@Amount,@Memo)

END
RETURN

实际上在我的第一个插入语句之后,我需要tbl_GL_Trans_Detailstemp的值 主键GL_trans_id将其插入下一个表...

因此,如果类型表@LIST有很多行(比如5),我需要逐个执行所有语句(作为循环工作)

但是到目前为止我已经检查过第一个插入语句起初是一个整体,然后只有下一个语句被激活。我怎么能克服这个?

更确切地说,我需要一个使用以下逻辑的解决方案

CREATE PROCEDURE [dbo].[usp_insertGl_transtemp2] 
@LIST [dbo].JNLOBJLIST READONLY,
@COUNT int
AS
DECLARE @id int
DECLARE @rowcount int=0
WHILE @rowcount<@COUNT
BEGIN

INSERT INTO tbl_GL_Trans_Detailstemp
                    ( trans_ref_number
                    , GL_trans_date
                    , GL_trans_amount
                    , GL_trans_remark
                    , company_branch_id
                    , GL_Account_id
                    , fiscal_year_id
                    , IsDebit
                    , Person
                    , tbl_reference_Id)

SELECT              @rowcount.strTransRefNumber
                    , @rowcount.dateGLTransDate
                    , @rowcount.decGLTransAmount
                    , @rowcount.strGLTransRemark
                    , @rowcount.guidCompanybranchId
                    , @rowcount.intGLAccountId
                    , @rowcount.intFiscalYearId
                    , @rowcount.boolGLIsDebit
                    , @rowcount.strPerson
                    , @rowcount.inttblReferenceId FROM @LIST

SET @id = (SELECT MAX(GL_trans_id)
FROM   tbl_GL_Trans_Detailstemp)


UPDATE    tbl_Gl_account
SET GL_Balance = GL_Balance + (SELECT @rowcount.decGLTransAmount2 FROM @LIST)
WHERE (GL_Account_id = (SELECT @rowcount.intGLAccountId FROM @LIST))

DECLARE @Journal_Master_Id int
DECLARE @Trans_Id int
DECLARE @Amount decimal
DECLARE @Memo varchar(50)

SET @Journal_Master_Id=(SELECT @rowcount.Journal_Master_Id FROM @LIST)
SET @Trans_Id=(@id)
SET @Amount=(SELECT @rowcount.decGLTransAmount FROM @LIST)
SET @Memo=(SELECT @rowcount.strJournalmemo FROM @LIST)

INSERT INTO tbl_Journal_Details
    (Journal_Master_Id, Trans_Id, Amount, Memo)
VALUES     (@Journal_Master_Id,@Trans_Id,@Amount,@Memo)

SET @rowcount = @rowcount + 1
END
RETURN

1 个答案:

答案 0 :(得分:1)

有可能避免循环并在查询中使用稍后INSERT的{​​{3}}。以下示例基于@list.strTransRefNumberUNIQUE的猜测。即使它不是UNIQUE,您仍然可以重构最后JOIN中的INSERT,因为您知道事情是如何相关的等等。

CREATE PROCEDURE [dbo].[usp_insertGl_transtemp2] 
@list [dbo].JNLOBJLIST READONLY
AS    
BEGIN
    BEGIN TRAN
        DECLARE @inserted TABLE ( id INT NOT NULL, strTransRefNumber VARCHAR(50) NOT NULL )

        INSERT INTO tbl_GL_Trans_Detailstemp
          ( trans_ref_number, GL_trans_date, GL_trans_amount, GL_trans_remark, company_branch_id
            , GL_Account_id, fiscal_year_id, IsDebit, Person, tbl_reference_Id ) 
        OUTPUT INSERTED.GL_trans_id, INSERTED.trans_ref_number INTO @inserted 
        SELECT strTransRefNumber, dateGLTransDate, decGLTransAmount, strGLTransRemark
           , guidCompanybranchId, intGLAccountId, intFiscalYearId, boolGLIsDebit
           , strPerson, inttblReferenceId 
        FROM @list

        -- refactored it to use a join which i think is what you need here
        UPDATE a
        SET a.GL_Balance = a.GL_Balance + l.decGLTransAmount2
        FROM tbl_Gl_account a
        JOIN @list l ON l.intGLAccountId = a.GL_Account_id

        INSERT INTO tbl_Journal_Details
            (Journal_Master_Id, Trans_Id, Amount, Memo)
        SELECT l.Journal_Master_Id, i.id, l.decGLTransAmount, l.strJournalmemo
        FROM @list l
        JOIN @inserted i ON i.strTransRefNumber = l.strTransRefNumber
    COMMIT
END
RETURN