如果只找到一条记录,确保不添加逗号,或者添加两条记录
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',
本质上,这将搜索适当的记录。如果它发现 LogBook1
、LogBook2
或 LogBook3
不存在记录,它将 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 ...
考虑下面的 SQL 查询,该查询旨在以 XML 的形式构建复杂的 return:
ISNULL(Logbook1 + ',', '') + ISNULL(Logbook2 + ',', '') + ISNULL(Logbook3 + ',', '') AS '@logBookNums',
本质上,这将搜索适当的记录。如果它发现 LogBook1
、LogBook2
或 LogBook3
不存在记录,它将 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 ...