使用存储过程中的游标从多个表中写入表

时间:2014-11-14 21:09:15

标签: sql stored-procedures cursor

我正在努力编写我的第一个程序来将数据从多个表中拉出来并使用游标将其写入另一个表以循环遍历所有数据。希望能在这里找到一些帮助。

我将6个表连接回主表Accounts,以显示所需的数据。使用第一个游标,我加入了五个表来获取所需的信息,然后我想再添加两个游标来从电话详细信息表中添加电话号码(主要和次要)。

希望这是有道理的。我确信我在SQL中遗漏了一些东西,但基本上我想循环访问Accounts表并将数据写入新表并循环遍历Phone Detail表并获取每个帐户的主要电话和然后是辅助电话(同时考虑一个NULL值),并将其写入新表。

CREATE PROCEDURE [dbo].[CRM_Account_Info] 
    @AccountID int,
    @AccountName nvarchar(128),
    @Bus_Type nvarchar(50),
    @AccountAddr1 nvarchar(128),
    @AccountAddr2 nvarchar(128),
    @AccountCity nvarchar(32),
    @AccountState nvarchar(10),
    @AccountZip nvarchar(10),
    @Account_Coll_Area_CodeID int,
    @Account_Coll_Area nvarchar(50),
    @Account_CRC_ID int,
    @Account_CRC_Name nvarchar(100),
    @Account_Prime_Number nvarchar(120),
    @Account_2nd_Number nvarchar(120)
AS
BEGIN
    -- Truncate Accounts table 
    Execute Immediate 'Truncate DBO.CRM_Accounts';

    -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Grab Account ID, Account Name, Account Type, Address, City, State, Zip, Collection Area ID, Collection Area Description,
    -- Recruiter ID, Recruiter Full Name from the Accounts Table

    Declare Acct_Info cursor for
        Select 
           Acct.AccountID, Acct.Internalname, 
           QC.Descshort, 
           AD.Addr1, AD.Addr2, AD.City, AD.State, AD.Zip,
           Sub.CodeID, Sub.Description, 
           Peo.PersonID, Peo.Fullname
        from 
           Accounts as Acct
        inner join 
           AddressDetail AD on Acct.AccountID = AD.AccountID
        inner join 
           CenterDetail CD on Acct.Centerid = CD.CenterID
        inner join 
           People Peo on Acct.LeaderID = Peo.PersonID
        inner join 
           IDViewOrgSubCenter SUB on CD.OrgSubCenter = SUB.CodeID
        inner join 
           QuickCodes QC on Acct.AccountType = QC.CodeID

    Open Acct_Info -- Open cursor

    Fetch Next from Acct_Info into @AccountID, @AccountName, @Bus_Type, @AccountAddr1, 
                                   @AccountAddr2, @AccountCity, @AccountState, @AccountZip,
                                   @Account_Coll_Area_CodeID, @Account_Coll_Area, 
                                   @Account_CRC_ID, @Account_CRC_Name, @Account_Prime_Number, 
                                   @Account_2nd_Number

    Close Acct_Info  -- Close cursor

    -- Grab the Primary Phone for the Account
    Declare Primary_Phone cursor for

Select top 1 Acct.AccountID, PD.FormattedNumber
From PhoneDetail PD
inner join Accounts Acct on PD.AccountID=Acct.AccountID
Where PD.PrimaryPhone=1
And PD.AccountID=@AccountID

Close Primary_Phone  -- Close cursor

-- Grab the second phone for an account

Declare Secondary_Phone cursor for

Select top 1 Acct.AccountID, PD.FormattedNumber
From PhoneDetail PD
inner join Accounts Acct on PD.AccountID=Acct.AccountID
Where PD.PrimaryPhone<>1
And PD.AccountID=@AccountID

Close Secondary_Phone  -- Close cursor

-- Insert the values into the CRM table
Insert CRM_Accounts (
AccountID,
AccountName,
Bus_Type,
AccountAddr1,
AccountAddr2,
AccountCity,
AccountState,
AccountZip,
Account_Coll_Area_CodeID,
Account_Coll_Area,
Account_CRC_ID,
Account_CRC_Name,
Account_Prime_Number,
Account_2nd_Number
)
Values (
@AccountID,
@AccountName,
@Bus_Type,
@AccountAddr1,
@AccountAddr2,
@AccountCity,
@AccountState,
@AccountZip,
@Account_Coll_Area_CodeID,
@Account_Coll_Area,
@Account_CRC_ID,
@Account_CRC_Name,
@Account_Prime_Number,
@Account_2nd_Number
)
END
GO

2 个答案:

答案 0 :(得分:0)

尝试将其全部放入一个查询中。我做了两个派生表,一个是主要的,一个是次要的,并给出了由accountid划分的行号。然后在连接中我只得到rownumber = 1,这样它每个accountid只返回一个数字。

 SELECT Acct.accountid,
       Acct.internalname,
       QC.descshort,
       AD.addr1,
       AD.addr2,
       AD.city,
       AD.state,
       AD.zip,
       Sub.codeid,
       Sub.description,
       Peo.personid,
       Peo.fullname,
       pd1.formattedNumber,
       pd2.formattedNumber
FROM   accounts AS Acct
       INNER JOIN addressdetail AD
               ON Acct.accountid = AD.accountid
       INNER JOIN centerdetail CD
               ON Acct.centerid = CD.centerid
       INNER JOIN people Peo
               ON Acct.leaderid = Peo.personid
       INNER JOIN idvieworgsubcenter SUB
               ON CD.orgsubcenter = SUB.codeid
       INNER JOIN quickcodes QC
               ON Acct.accounttype = QC.codeid  
       LEFT JOIN (select accountid, formattednumber, primaryphone, row_number() over(partition by accountid order by formattednumber) as rNum  
                           from phonedetail where primaryphone = 1) pd1
                ON acct.accountid = pd1.accountid and pd1.rNum = 1
       LEFT JOIN (select accountid, formattednumber, primaryphone, row_number() over(partition by accountid order by formattednumber) as rNum  
                           from phonedetail where primaryphone <> 1) pd2
                ON acct.accountid = pd2.accountid and pd2.rNum = 1

答案 1 :(得分:0)

@JChao,我正确认为你的答案是正确的,因为SQL工作得非常出色,但是我想根据收到的建议在这里发布这个,并且现在可以继续查看这个程序。它似乎有效,但我喜欢更有经验的用户查看它是否发现任何明显的错误:

第一步是删除(或截断)当前表中的所有数据,然后将select语句写入我的新表:

Create Procedure Update_CRM_Accts
--Alter Procedure Update_CRM_Accts
As
Begin
Truncate Table CRM_Accounts
SET NOCOUNT ON;
Insert into CRM_Accounts
Select Acct.AccountID,
   Acct.InternalName,
   QC.DescShort,
   AD.Addr1,
   AD.Addr2,
   AD.City,
   AD.State,
   AD.Zip,
   Sub.CodeID,
   Sub.Description,
   Peo.PersonID,
   Peo.FullName,
   PD1.FormattedNumber as 'Primary_Number',
   PD2.FormattedNumber as 'Secondary_Number'
From Accounts As Acct
INNER JOIN addressdetail AD ON Acct.AccountID = AD.AccountID
INNER JOIN CenterDetail CD ON Acct.CenterID = CD.CenterID
INNER JOIN People Peo ON Acct.LeaderID = Peo.PersonID
INNER JOIN IDViewOrgSubCenter SUB ON CD.OrgSubcenter = SUB.CodeID
INNER JOIN quickcodes QC ON Acct.AccountType = QC.CodeID  
LEFT OUTER JOIN (Select AccountID, FormattedNumber, PrimaryPhone, row_number() over(partition by AccountID order by FormattedNumber) as rNum  
       From PhoneDetail where PrimaryPhone = 1) PD1
            ON Acct.accountid = PD1.AccountID and PD1.rNum = 1
LEFT OUTER JOIN (Select AccountID, FormattedNumber, PrimaryPhone, row_number() over(partition by AccountID order by FormattedNumber) as rNum  
       From PhoneDetail where PrimaryPhone <> 1) PD2
            ON Acct.AccountID = PD2.AccountID and PD2.rNum = 1
End
Go