2011-07-31 119 views
1

我有以下SP:連接具有XML PATH

CREATE PROCEDURE AdvancedSearch 
    @MechanicID nvarchar(50), 
    @done bit, 
    @sDate datetime, 
    @eDate datetime 
AS 
SELECT VehicleData.*, Vehicle.*, C5.dbo.debkart.navn, 
      C5.dbo.DEBKART.ADRESSE1, C5.dbo.debkart.adresse2, 
      Mechanic.MechanicName 
FROM  (((Vehicle INNER JOIN VehicleData ON Vehicle.ID = VehicleData.IDRegistrationNumber) 
      INNER JOIN C5.dbo.debkart ON Vehicle.KeyC5 = c5.dbo.debkart.LXbenummer 
      INNER JOIN Mechanic_VehicleData ON VehicleData.ID = Mechanic_VehicleData.PK_VehicleData)) 
      INNER JOIN Mechanic ON Mechanic_VehicleData.PK_Mechanic = Mechanic.ID 
WHERE (@MechanicID IS NULL OR Mechanic.ID = @MechanicID) AND 
      (@done IS NULL OR VehicleData.Done = @done) AND 
      ((@sDate IS NULL OR @eDate IS NULL) OR VehicleData.DATE BETWEEN @sDate AND @eDate) 
GO 

我想串連跨越與同一VehicleData.ID所有行MechanicName柱所以想確切地做,因爲這文章在這裏:Concatenate with XML Path 但只有一個是機械師姓名。

我的問題是,我無法弄清楚如何從我的SP中的帖子插入sql代碼。

有人可以幫助我嗎?

更新:我得到的東西的工作,我做了這一點,它好像又回到了我的需要,但有一個問題,我描述了進一步下跌:

SELECT VehicleData.*, Vehicle.*, C5.dbo.debkart.navn, C5.dbo.DEBKART.ADRESSE1, C5.dbo.debkart.adresse2, 
    STUFF(
    (SELECT 
    ',' + MechanicName 
    FROM Mechanic m 
    INNER JOIN Mechanic_VehicleData vm ON m.ID = vm.PK_Mechanic 
    WHERE vm.PK_VehicleData = VehicleData.ID 
    FOR XML PATH('')), 1, 1, '' 
    ) AS 'Mechanics' 
FROM (((Vehicle INNER JOIN VehicleData ON Vehicle.ID = VehicleData.IDRegistrationNumber)   
INNER JOIN C5.dbo.debkart ON Vehicle.KeyC5 = c5.dbo.debkart.LXbenummer)) 
ORDER BY VehicleData.ID 

,所以我就到我需要的部分添加WHERE子句,現在我不知道放置在哪裏。我有一種搜索特定的MechanicID,完成標誌和一些日期的方法。我應該在哪裏放這些?

更新2

@thanks馬克幫了我,我仍然有一個 「小」 問題,雖然:)

下面是最終SP:

CREATE PROCEDURE AdvancedSearch 
@MechanicID nvarchar(50), 
@done bit, 
@sDate datetime, 
@eDate datetime 
AS 
SELECT VehicleData.*, Vehicle.*, C5.dbo.debkart.navn, C5.dbo.DEBKART.ADRESSE1, C5.dbo.debkart.adresse2, 
    STUFF(
    (SELECT 
    ',' + MechanicName 
    FROM Mechanic m 
    INNER JOIN Mechanic_VehicleData vm ON m.ID = vm.PK_Mechanic 
    WHERE vm.PK_VehicleData = VehicleData.ID 
    FOR XML PATH('')), 1, 1, '' 
    ) AS 'Mechanics' 
FROM (Vehicle 
INNER JOIN VehicleData ON Vehicle.ID = VehicleData.IDRegistrationNumber   
INNER JOIN C5.dbo.debkart ON Vehicle.KeyC5 = c5.dbo.debkart.LXbenummer), Mechanic, Mechanic_VehicleData 
WHERE VehicleData.ID = Mechanic_VehicleData.PK_VehicleData 
AND Mechanic.ID = Mechanic_VehicleData.PK_Mechanic 
AND (@MechanicID IS NULL OR Mechanic.ID = @MechanicID) 
AND (@done IS NULL OR VehicleData.Done = @done) 
AND ((@sDate IS NULL OR @eDate IS NULL) OR VehicleData.Date BETWEEN @sDate AND @eDate) 
GO 

如上所述,它工作正常。我遇到的問題是,如果我運行EXECUTE AdvancedSearch null, null, null, null查詢需要4秒鐘才能完成。如果我從SP運行查詢,則不需要任何時間。我覺得很奇怪。爲什麼SP需要更長的時間?

回答

5

嘗試先簡化您的示例,然後弄清楚如何在簡化示例中執行此步驟 - 然後您可以將其整合到您的整體查詢中。

嘗試這一點 - 它在我的設置:

DECLARE @vehicle TABLE (VehID INT, VehName VARCHAR(50)) 
DECLARE @mechanic TABLE (MechanicID INT, MechanicName VARCHAR(50)) 
DECLARE @VehicleMechanic TABLE (VehID INT, MechanicID INT) 

INSERT INTO @vehicle(VehID, VehName) VALUES(1, 'BMW 330i'),(2, 'Mini Cooper') 

INSERT INTO @mechanic(MechanicID, MechanicName) 
VALUES (1, 'Joe'), (2, 'Jeff'), (3, 'Bob'), (4, 'Steve') 

INSERT INTO @VehicleMechanic(VehID, MechanicID) 
VALUES (1, 1), (1, 2), (2, 1), (2, 3), (2, 4) 

SELECT 
    v.VehID, VehName, 
    STUFF(
    (SELECT 
     ',' + MechanicName 
    FROM @mechanic m 
    INNER JOIN @VehicleMechanic vm ON m.MechanicID = vm.MechanicID 
    WHERE vm.VehID = v.VehID 
    FOR XML PATH('')), 1, 1, '' 
    ) AS 'Mechanics' 
FROM @vehicle v 

給我的輸出:

VehID VehName  Mechanics 
    1 BMW 330i  Joe,Jeff 
    2 Mini Cooper Joe,Bob,Steve 

更新:很難驗證什麼,不是有你手頭的數據庫 - 但試試這個:

SELECT 
    vd.*, v.*, d.navn, d.ADRESSE1, D.adresse2, 
    STUFF(
     (SELECT 
     ',' + MechanicName 
     FROM dbo.Mechanic m 
     INNER JOIN dbo.Mechanic_VehicleData vm ON m.ID = vm.PK_Mechanic 
     WHERE vm.PK_VehicleData = v.ID 
     FOR XML PATH('')), 1, 1, '' 
    ) AS 'Mechanics' 
FROM dbo.Vehicle v 
INNER JOIN dbo.VehicleData vd ON v.ID = vd.IDRegistrationNumber 
-- if you need the mechnic, add this JOIN  
INNER JOIN dbo.Vehicle_Mechanic vm ON vm.VehicleID = v.VehicleID 
INNER JOIN C5.dbo.debkart d ON v.KeyC5 = d.LXbenummer 

WHERE     -- add your WHERE clause here 
    vd.DoneFlag = 1  
    AND vd.SomeDate = GETDATE() 
    AND vm.MechanicID = 4711   -- check for your specific mechanic 
ORDER BY 
    vd.ID 

如果它不起作用 - 可以你告訴我們,如果你得到一個錯誤(和它是什麼),或者你是否得到錯誤的輸出 - 它有什麼問題?

任何WHERE子句應該被添加到外SELECT聲明 - 內東西是隻用於設置VehicleDataMechanic_VehicleDataMechanic表之間的關係。

+0

謝謝,我試過,但我仍然無法讓它工作。當我需要將它集成到我的最終SP中時,我的問題就出現了。我甚至得到了工作的例子,但只要我去集成我失敗:( – dbrasco

+0

我更新了上面的帖子,我很感激,如果你可以幫助 – dbrasco

+0

我試過你的建議,如果我添加WHERE Mechanic_VehicleData.ID = 1或Mechanic.ID = 1我剛剛得到'多部分標識符'Mechanic_VehicleData。ID「無法綁定」,我相信這是因爲它沒有包含在select中,但我怎麼能添加它,因爲eache Vehicle的ID會是多個,所以WHERE必須在名稱連接之前完成。有道理我想說什麼,如果是的話,我該如何解決它? – dbrasco