Sql 与XML路径连接

Sql 与XML路径连接,sql,sql-server,Sql,Sql Server,我有以下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,

我有以下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,
          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
我希望将MechanicName列连接到具有相同VehicleData.ID的所有行中,以便与本文中的操作完全相同: 但只有一个字段是MechanicName

我的问题是,我不知道如何在SP中插入post中的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子句的部分,现在我不知道应该把它们放在哪里。我有一种搜索特定机械ID、完成标志和一些日期的方法。我现在应该把这些放在哪里

更新2

@多亏马克帮了我的忙,我还是有个小问题:

以下是最后一个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

如前所述,它工作得很好。我遇到的问题是,如果我运行executeadvancedsearch null,null,null,null,查询需要4秒钟才能完成。如果在SP之外运行查询,则不需要花费时间。我觉得很奇怪。为什么SP需要更长的时间?

首先尝试简化您的示例,然后在简化的示例中找出如何执行此步骤,然后您可以将其重新集成到整个查询中

试试这个-它在我的设置中起作用:

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语句中-内部内容仅用于设置VehicleData、Mechanical\u VehicleData和Mechanical表之间的关系。

首先尝试简化示例,然后在简化的示例中找出如何执行这一步骤,然后可以将其重新集成到整个查询中

试试这个-它在我的设置中起作用:

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语句中-内部内容仅用于设置VehicleData、Mechanical\u VehicleData和Mechanical表之间的关系。

谢谢,我尝试过,但仍然无法使其正常工作。当我需要将它集成到我的终端SP时,我的问题就出现了。我甚至得到了一个可以工作的示例,但一旦我进行了集成,我就失败了:我尝试了你的建议,如果我添加了其中的mechanical\u VehicleData.ID=1或mechanical.ID=1,我只得到了多部分标识符mechanical\u VehicleData.ID无法绑定,我相信这是因为它是不包括在选择中,但我如何添加它,因为每个车辆的ID都是多个的,因此必须在连接名称之前完成WHERE。我想说的有意义吗?如果有,我该如何解决?我还尝试将表Mechanical\u Vehicle或Mechanical添加到FROM子句中,因此,我尝试了dbo.Vehicle v,而不是您编写的dbo.Vehicle v,dbo.vehicledatao但我知道它不能很好地找到v.IDv@donnib:更新了我的回复,以便可以在机械IDI上进行选择。我还纠正了我的性能问题。我刚刚创建了一些本地参数,并在SP中使用了这些参数。谢谢,我尝试了,但仍然无法使其工作。当我需要将它集成到我的终端SP时,我的问题就出现了。我甚至得到了一个可以工作的示例,但一旦我进行了集成,我就失败了:我尝试了你的建议,如果我添加了其中的mechanical\u VehicleData.ID=1或mechanical.ID=1,我只得到了多部分标识符mechanical\u VehicleData.ID无法绑定,我相信这是因为它是不包括在选择中,但我如何添加它,因为每个车辆的ID都是多个的,因此必须在连接名称之前完成WHERE。我想说的有意义吗?如果有,我该如何解决?我还尝试将表Mechanical\u Vehicle或Mechanical添加到FROM子句中,因此,我尝试了dbo.Vehicle v,而不是您编写的dbo.Vehicle v,dbo.vehicledatao但我知道它不能很好地找到v.IDv@donnib:更新了我的回复,以便可以在机械IDI上进行选择。我还纠正了我的性能问题。我刚刚创建了一些本地参数,并在SP中使用了这些参数。