2009-08-05 12 views
1

J'ai deux tables temporaires, quand je fais le cycle à travers une table et j'obtiens quelques valeurs, dans ce cycle j'ai besoin d'insérer une nouvelle ligne dans une autre table temporaire. Est-ce possible. Voici mon code SQL et des informations d'erreur:Serveur Sql - comment insérer une ligne unique dans une table temporaire?

Alter PROCEDURE ProfitReportQ_Search_WithSub 
(@DateFrom datetime, 
@DateTo datetime, 
@DateActive bit, 
@UserID int, 
@ItemGroupIDValues nvarchar(max) 
) 
AS 
BEGIN 
CREATE TABLE #tmp(ItemGroupID int, ItemGroupName nvarchar(250), Manager nvarchar(250), AllQuantity int, AllSumPrice AllSumPrice, AllSumPriceWithVAT decimal(18,4), Profit decimal(18,4)) 
CREATE TABLE #tmp2(Manager nvarchar(250), AllQuantity int, AllSumPrice decimal(18,4), AllSumPriceWithVAT decimal(18,4), Profit decimal(18,4), ItemGroupNameRoot nvarchar(250)) 


INSERT INTO #tmp 
    EXEC ProfitReportQ_Search @DateFrom, @DateTo, @DateActive, @UserID, @ItemGroupIDValues 

DECLARE @ItemGroupID int 
DECLARE @ItemGroupName nvarchar(250) 
DECLARE @Manager nvarchar(250) 
DECLARE @AllQuantity int 
DECLARE @AllSumPrice decimal(18,4) 
DECLARE @AllSumPriceWithVAT decimal(18,4) 
DECLARE @Profit decimal(18,4) 
DECLARE @ItemGroupNameRoot nvarchar(250) 
DECLARE @count int 

SET @count = (SELECT COUNT(*) FROM #tmp) 
WHILE (@count <> 0) 
BEGIN 
    SELECT TOP (1) @ItemGroupID = ItemGroupID, @ItemGroupName = ItemGroupName, @Manager = Manager, @AllQuantity = AllQuantity, @AllSumPrice = AllSumPrice, @AllSumPriceWithVAT = AllSumPriceWithVAT, @Profit = Profit FROM #tmp 
    DELETE #tmp WHERE ItemGroupID = ItemGroupID AND ItemGroupName = @ItemGroupName AND Manager = @Manager AND AllQuantity = @AllQuantity AND AllSumPrice = @AllSumPrice AND AllSumPriceWithVAT = @AllSumPriceWithVAT AND Profit = @Profit 



    INSERT INTO #tmp2 (Manager, AllQuantity, AllSumPrice, AllSumPriceWithVAT, Profit, ItemGroupNameRoot) 
     VALUES (@Manager, @AllQuantity, @AllSumPrice, @AllSumPriceWithVAT, @Profit, EXEC ItemGroup_GetRootWithRecurse @ItemGroupID) 
END 


SELECT ItemGroupNameRoot, Manager, SUM(AllQuantity) AS AllQuantity, SUM(AllSumPrice) AS AllSumPrice, 
     SUM(AllSumPriceWithVAT) AS AllSumPriceWithVAT, SUM(Profit) AS Profit 
FROM #tmp2 
GROUP BY ItemGroupNameRoot, Manager 

DELETE #tmp 
DELETE #tmp2 

END 
GO 

Il y a un problème avec ces lignes:

INSERT INTO #tmp2 (Manager, AllQuantity, AllSumPrice, AllSumPriceWithVAT, Profit, ItemGroupNameRoot) 
     VALUES (@Manager, @AllQuantity, @AllSumPrice, @AllSumPriceWithVAT, @Profit, EXEC ItemGroup_GetRootWithRecurse @ItemGroupID) 

Erreur:

syntaxe incorrecte près du mot-clé 'EXEC'. Syntaxe incorrecte près de ')'.

Quelques idées?

Répondre

1

Il n'était pas possible pour moi de mettre ces valeurs dans # temp2 quand il était exécuté dans un autre SP. je travaillais avec trois tables temporaires, comme ceci:

BEGIN

CREATE TABLE #tmp(ItemGroupID int, ItemGroupName nvarchar(250), 
        Manager nvarchar(250), AllQuantity int, 
        AllSumPrice decimal(18,4), AllSumPriceWithVAT decimal(18,4), 
        Profit decimal(18,4), ID int 
        ) 
CREATE TABLE #tmp2(Manager nvarchar(250), AllQuantity int, 
        AllSumPrice decimal(18,4), AllSumPriceWithVAT decimal(18,4), 
        Profit decimal(18,4), ItemGroupNameRoot nvarchar(250) 
        ) 

CREATE TABLE #tmp3(ItemGroupNameRoot nvarchar(250)) 


INSERT INTO #tmp 
    EXEC ProfitReportQ_Search_v2 @DateFrom, @DateTo, @DateActive, @UserID, @ItemGroupIDValues 

DECLARE @ID int 
DECLARE @ItemGroupID int 
DECLARE @ItemGroupName nvarchar(250) 
DECLARE @Manager nvarchar(250) 
DECLARE @AllQuantity int 
DECLARE @AllSumPrice decimal(18,4) 
DECLARE @AllSumPriceWithVAT decimal(18,4) 
DECLARE @Profit decimal(18,4) 
DECLARE @ItemGroupNameRoot nvarchar(250) 
DECLARE @count int 

SET @count = (SELECT COUNT(*) FROM #tmp) 
WHILE (@count <> 0) 
BEGIN 
    SELECT TOP (1) @ItemGroupID = ItemGroupID, @ItemGroupName = ItemGroupName, @Manager = Manager, @AllQuantity = AllQuantity, @AllSumPrice = AllSumPrice, @AllSumPriceWithVAT = AllSumPriceWithVAT, @Profit = Profit, @ID = ID 
    FROM #tmp 
    DELETE #tmp WHERE ID = @ID 

    INSERT INTO #tmp3 EXEC ItemGroup_GetRootWithRecurse_ForProfitReport @ItemGroupID 
    SELECT TOP(1)@ItemGroupNameRoot = ItemGroupNameRoot 
    FROM #tmp3 


    INSERT INTO #tmp2 SELECT @Manager, @AllQuantity, 
        @AllSumPrice, @AllSumPriceWithVAT, 
        @Profit, @ItemGroupNameRoot 
    DELETE #tmp3 
    SET @count = (SELECT COUNT(*) FROM #tmp) 
END 
DELETE #tmp 
SELECT ItemGroupNameRoot, Manager, SUM(AllQuantity) AS AllQuantity, SUM(AllSumPrice) AS AllSumPrice, 
     SUM(AllSumPriceWithVAT) AS AllSumPriceWithVAT, SUM(Profit) AS Profit 
FROM #tmp2 
GROUP BY ItemGroupNameRoot, Manager 
DELETE #tmp2 

FIN GO

+0

J'ai également essayé avec la table temporaire globale, (## tmp) il n'a pas non plus fonctionné, ainsi la question principale change en "Comment partager la table temporaire entre les procédures stockées?" – Vytas

0

Il semble que vous essayez d'insérer le résultat de ce qui suit dans une colonne de # tmp2 ItemGroupNameRoot:

EXEC ItemGroup_GetRootWithRecurse @ItemGroupID 

Vous ne pouvez vraiment pas exécuter des procédures stockées et utiliser les résultats de cette façon. Au lieu de cela, je suggère de remplacer la procédure stockée ItemGroup_GetRootWithRecurse par une fonction définie par l'utilisateur. Cela peut ressembler à ceci:

CREATE FUNCTION ItemGroup_GetRootWithRecurse_Function (@ItemGroupID int) 
RETURNS varchar(30) 
AS 
BEGIN 
declare @Return varchar(30) 
select @return = case @ItemGroupID 
when 1 then 'One' 
when 2 then 'Two' 
else 'Three' 
end 

return @return 
end 

Vous appelez la fonction presque de la même manière que la procédure stockée. La grande différence est que vous supprimez l'instruction EXEC afin que l'appel ressemble à ceci:

dbo.ItemGroup_GetRootWithRecurse_Function (@ItemGroupID) 

J'espère que cela aide.

+0

Ce problème est avec récursion, je ne peux pas mettre ce genre de choses sql en fonction.Mon sql reculsion dans ItemGroup_GetRootWithRecurse loks comme celui-ci (deuxième commentaire) – Vytas

+0

@ItemGroupID int AS COMMENCE AVEC recurseUp AS (SELECT ItemGroupID, ParentID, ItemGroupName DE dbo.ItemGroup \t \t \t \t \t \t \t \t \t \t \t OÙ ItemGroupID = @ItemGroupID UNION ALL CHOISIR b.ItemGroupID, b.ParentID, b.ItemGroupName FROM recurseUp COMME INNER JOIN dbo.ItemGroup AS b O N a.ParentID = b.ItemGroupID) SELECT ItemGroupID, ItemGroupName DE recurseUp AS recurseUp_1 OU (ParentID IS NULL) FIN – Vytas

+0

Le problèm est que la fonction ne prend pas en charge "par" clause. – Vytas

0

réponse courte:
Vous pouvez partager une table temporaire créée dans une procédure stockée avec une procédure stockée qui appelle. Vous pouvez essayer d'utiliser cette technique pour insérer dans # temp2 dans ItemGroup_GetRootWithRecurse.

longue réponse:
cela peut aider: How to Share Data Between Stored Procedures. Vous pouvez lire l'intégralité de l'article, mais la section liée sur le partage des tables temporaires entre les procédures mon tour.

vous pouvez passer @Manager, @AllQuantity, @AllSumPrice, @AllSumPriceWithVAT, @Profit ainsi que @ItemGroupID dans ItemGroup_GetRootWithRecurse, et à l'intérieur, insérer dans # tmp2 avec quelque chose comme:

WITH recurseUp AS 
(
SELECT ItemGroupID, ParentID, ItemGroupName 
FROM dbo.ItemGroup 
WHERE ItemGroupID = @ItemGroupID 

UNION ALL 
SELECT b.ItemGroupID, b.ParentID, b.ItemGroupName 
FROM recurseUp AS a 
INNER JOIN dbo.ItemGroup AS b ON a.ParentID = b.ItemGroupID 
) 
INSERT INTO #temp2 (Manager, AllQuantity, AllSumPrice, AllSumPriceWithVAT, Profit, ItemGroupNameRoot) 
SELECT @Manager, @AllQuantity, @AllSumPrice, @AllSumPriceWithVAT, @Profit, ItemGroupName 
FROM recurseUp AS recurseUp_1 WHERE (ParentID IS NULL) END 

ce code peut être un peu éteint, puisque je n'ai pas tous les détails, mais devrait être proche.