如果只找到一条记录,确保不添加逗号,或者添加两条记录

Ensuring that a comma is not added if only one record is found, or that both are added

考虑下面的 SQL 查询,该查询旨在以 XML 的形式构建复杂的 return:

ISNULL(Logbook1 + ',', '') + ISNULL(Logbook2 + ',', '') + ISNULL(Logbook3 + ',', '') AS '@logBookNums',

本质上,这将搜索适当的记录。如果它发现 LogBook1LogBook2LogBook3 不存在记录,它将 return 一个空字符串。如果它在 LogBook1 中找到一条记录,它将 return 和一个尾随逗号。

不幸的是,这个 XML 发送到的 WCF 服务的记录令人震惊(实际上是 none 无论如何)并且它拒绝带有尾随逗号的单个日志编号。

我的猜测是它应该提交为:

logBookNums="12345,,"

logBookNums="12345"

我应该如何更改上面的 SQL 行以输出一个或另一个,并且(如果查询找到两个日志编号)生成如下输出:

logBookNums="12345,12346,"

logBookNums="12345,12346"

这是整个查询,我需要插入一个解决方案来处理@logBookNums 和@landingDecNums 的这种困境。

CREATE PROCEDURE dbo.CreateErsSalesAddSubmissionXmlByDateRange

-- Add the parameters for the stored procedure here

@uname VARCHAR(10) ,
        @pword VARCHAR(10) ,
        @sntype VARCHAR(1) ,
        @action VARCHAR(10) ,
        @salesContractRef VARCHAR(10),

        @auctionId NCHAR(10) ,
        @startDate  DATE,
        @endDate DATE


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

  -- Insert statements for procedure here


 SELECT
    RTRIM(@uname) AS '@uname',
    RTRIM(@pword) AS '@pword',

    (SELECT

        @snType AS '@snType',
        RTRIM(@action) AS '@action',
        COALESCE(@salesContractRef, '') AS '@salesContractRef',
        CONVERT(VARCHAR(10), DateOfPurchase, 112) AS '@saleDate',
        RTRIM(COALESCE(@auctionID, '')) AS '@auctionID',
        ISNULL(Logbook1 + ',', '') + ISNULL(Logbook2 + ',', '') + ISNULL(Logbook3 + ',', '') AS '@logBookNums',
        ISNULL(LandingDecNumber1 + ',', '') + ISNULL(LandingDecNumber2 + ',', '') + ISNULL(LandingDecNumber3 + ',', '') AS '@landingDecNums',
        COALESCE(VesselName, '') AS '@vesselName',
        RTRIM(VesselPLN) AS '@vesselPln',
        RTRIM(VesselOwner) AS '@vesselMasterOwner',
        COALESCE(CONVERT(VARCHAR(10), LandingDate1, 112), '') AS '@landingDate1',
        COALESCE(CONVERT(VARCHAR(10), LandingDate2, 112), '') AS '@landingDate2',
        COALESCE(CONVERT(VARCHAR(10), LandingDate3, 112), '') AS '@landingDate3',
        RTRIM(CountryOfLanding) AS '@countryOfLanding',
        RTRIM(PortOfLanding) AS '@landingPortCode',
      RTRIM(lh1.LandingId) AS '@internalRef',
        (SELECT

            COALESCE(RTRIM(SpeciesCode),'') AS '@speciesCode',
            RTRIM(FishingArea) AS '@faoAreaCode',
            COALESCE(RTRIM(IcesZone),'') AS '@ZoneCode',
            COALESCE(RTRIM(ld.DisposalCode),'') AS '@disposalCode',
            COALESCE(ld.FreshnessGrade,'') AS '@freshnessCode',
            COALESCE(ld.ProductSize,'') AS '@sizeCode',
            COALESCE(ld.PresentationCode,'') AS '@presentationCode',
            COALESCE(ld.PresentationState,'') AS '@stateCode',
            RTRIM(ld.NumberOfFish) AS '@numberOfFish',
            FORMAT(ld.Quantity, 'N2') AS '@weightKgs',
            FORMAT(Quantity * ld.UnitPrice, 'N2') AS '@value',
            COALESCE(ld.Currency,'') AS '@currencyCode',
            RTRIM(ld.WithdrawnDestinationCode) AS '@withdrawnDestinationCode',
            RTRIM(ld.BuyersRegistrationCode) AS '@buyerReg',
            RTRIM(ld.SalesContractRef) AS '@salesContractRef'

        FROM LandingDetails ld
        JOIN LandingHeaders lh
            ON ld.LandingId = lh.LandingId
        WHERE ld.LandingId = lh1.LandingId
        FOR XML PATH ('salesline'), TYPE)



    FROM LandingHeaders lh1

    WHERE lh1.AllocatedErsId IS NULL AND lh1.LandingDate1 BETWEEN @startDate     AND @endDate
    ORDER BY VesselName,lh1.LandingId

    FOR XML PATH ('salesnote'), TYPE)
FOR XML PATH ('ers')



END
GO

编辑(我在下面的回答中尝试过)

 SELECT
    RTRIM(@uname) AS '@uname'
   ,RTRIM(@pword) AS '@pword'
   ,(SELECT

        @snType AS '@snType'
       ,RTRIM(@action) AS '@action'
       ,COALESCE(@salesContractRef, '') AS '@salesContractRef'
       ,CONVERT(VARCHAR(10), DateOfPurchase, 112) AS '@saleDate'
       ,RTRIM(COALESCE(@auctionID, '')) AS '@auctionID'
       ,(
        SELECT ',' + CAST(LogbookX AS VARCHAR(100))
         FROM
        (
            VALUES(Logbook1),(Logbook2),(Logbook3)
        ) AS x(LogbookX)
        FOR XML PATH('')
    ),1,1,'') 
AS NumList(Concatenated)
WHERE NumList.Concatenated IS NOT NULL AS '@logBookNums'
                ,ISNULL(LandingDecNumber1 + ',', '') + ISNULL(LandingDecNumber2 + ',', '') + ISNULL(LandingDecNumber3 + ',', '') AS '@landingDecNums'
       ,COALESCE(VesselName, '') AS '@vesselName'
       ,RTRIM(VesselPLN) AS '@vesselPln'
       ,RTRIM(VesselOwner) AS '@vesselMasterOwner'
       ,COALESCE(CONVERT(VARCHAR(10), LandingDate1, 112), '') AS '@landingDate1'
       ,COALESCE(CONVERT(VARCHAR(10), LandingDate2, 112), '') AS '@landingDate2'
       ,COALESCE(CONVERT(VARCHAR(10), LandingDate3, 112), '') AS '@landingDate3'
       ,RTRIM(CountryOfLanding) AS '@countryOfLanding'
       ,RTRIM(PortOfLanding) AS '@landingPortCode'
       ,RTRIM(lh1.LandingId) AS '@internalRef'

额外编辑以帮助澄清下面答案中的评论

完整修改后的查询现在如下所示:

CREATE PROCEDURE dbo.CreateErsSalesAddSubmissionXmlByDateRange

-- Add the parameters for the stored procedure here

@uname VARCHAR(10),
@pword VARCHAR(10),
@sntype VARCHAR(1),
@action VARCHAR(10),
@salesContractRef VARCHAR(10),

@auctionId NCHAR(10),
@startDate DATE,
@endDate DATE


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

  -- Insert statements for procedure here


  SELECT
    RTRIM(@uname) AS '@uname'
   ,RTRIM(@pword) AS '@pword'
   ,(SELECT

        @snType AS '@snType'
       ,RTRIM(@action) AS '@action'
       ,COALESCE(@salesContractRef, '') AS '@salesContractRef'
       ,CONVERT(VARCHAR(10), DateOfPurchase, 112) AS '@saleDate'
       ,RTRIM(COALESCE(@auctionID, '')) AS '@auctionID'
       ,STUFF
        ((SELECT
            ',' + CAST(LogbookX AS VARCHAR(100))
          FROM (
          VALUES (Logbook1), (Logbook2), (Logbook3)
          ) AS x (LogbookX)
          FOR XML PATH (''))
        , 1, 1, '')
        AS '@logBookNums'

       ,ISNULL(LandingDecNumber1 + ',', '') + ISNULL(LandingDecNumber2 + ',', '') + ISNULL(LandingDecNumber3 + ',', '') AS '@landingDecNums'
       ,COALESCE(VesselName, '') AS '@vesselName'
       ,RTRIM(VesselPLN) AS '@vesselPln'
       ,RTRIM(VesselOwner) AS '@vesselMasterOwner'
       ,COALESCE(CONVERT(VARCHAR(10), LandingDate1, 112), '') AS '@landingDate1'
       ,COALESCE(CONVERT(VARCHAR(10), LandingDate2, 112), '') AS '@landingDate2'
       ,COALESCE(CONVERT(VARCHAR(10), LandingDate3, 112), '') AS '@landingDate3'
       ,RTRIM(CountryOfLanding) AS '@countryOfLanding'
       ,RTRIM(PortOfLanding) AS '@landingPortCode'
       ,RTRIM(lh1.LandingId) AS '@internalRef'
       ,(SELECT

            COALESCE(RTRIM(SpeciesCode), '') AS '@speciesCode'
           ,RTRIM(FishingArea) AS '@faoAreaCode'
           ,COALESCE(RTRIM(IcesZone), '') AS '@ZoneCode'
           ,COALESCE(RTRIM(ld.DisposalCode), '') AS '@disposalCode'
           ,COALESCE(ld.FreshnessGrade, '') AS '@freshnessCode'
           ,COALESCE(ld.ProductSize, '') AS '@sizeCode'
           ,COALESCE(ld.PresentationCode, '') AS '@presentationCode'
           ,COALESCE(ld.PresentationState, '') AS '@stateCode'
           ,RTRIM(ld.NumberOfFish) AS '@numberOfFish'
           ,FORMAT(ld.Quantity, 'N2') AS '@weightKgs'
           ,FORMAT(Quantity * ld.UnitPrice, 'N2') AS '@value'
           ,COALESCE(ld.Currency, '') AS '@currencyCode'
           ,RTRIM(ld.WithdrawnDestinationCode) AS '@withdrawnDestinationCode'
           ,RTRIM(ld.BuyersRegistrationCode) AS '@buyerReg'
           ,RTRIM(ld.SalesContractRef) AS '@salesContractRef'

          FROM LandingDetails ld
          JOIN LandingHeaders lh
            ON ld.LandingId = lh.LandingId
          WHERE ld.LandingId = lh1.LandingId
          FOR XML PATH ('salesline'), TYPE)



      FROM LandingHeaders lh1

      WHERE lh1.AllocatedErsId IS NULL
      AND lh1.LandingDate1 BETWEEN @startDate AND @endDate
      ORDER BY VesselName, lh1.LandingId

      FOR XML PATH ('salesnote'), TYPE)
  FOR XML PATH ('ers')



END
GO

当有 logBookNums 时,我们的格式就会正确 xml,如下所示。

然而,如果没有,我们应该得到 logBookNums="",但如您所见,我们什么也得不到。

你可以这样试试

您需要 "IN" 搜索,没有像 aNumber='123,345,678'

这样的搜索
DECLARE @tbl TABLE(Logbook1 INT,Logbook2 INT,Logbook3 INT);
INSERT INTO @tbl VALUES
 (12345,23456,56789)
,(234,NULL,NULL)
,(NULL,123,NULL)
,(NULL,NULL,NULL);

SELECT 'logbBookNums IN(' + NumList.Concatenated +')'
FROM @tbl
CROSS APPLY
(
SELECT STUFF
(
    (
        SELECT ',' + CAST(LogbookX AS VARCHAR(100))
         FROM
        (
            VALUES(Logbook1),(Logbook2),(Logbook3)
        ) AS x(LogbookX)
        FOR XML PATH('')
    ),1,1,'') 
)AS NumList(Concatenated)
WHERE NumList.Concatenated IS NOT NULL

结果

logbBookNums IN(12345,23456,56789)
logbBookNums IN(234)
logbBookNums IN(123)

那你可以写成Case When结构,没那么长:

CASE WHEN Logbook1 is not null
        THEN 
            CASE WHEN Logbook2 is not null
                THEN 
                    CASE WHEN Logbook2 is not null
                    THEN Logbook1+','+Logbook2+','+Logbook3
                    ELSE Logbook1+','+Logbook2
                ELSE  
                    CASE WHEN Logbook3 is not null
                    THEN Logbook1+','+Logbook3
                    ELSE Logbook1
        ELSE CASE WHEN ...