SQL Server参数化的存储过程联合,所有这些都取决于左联接的条件

问题描述 投票:0回答:2

我想执行UNION ALL查询,以便我可以根据在搜索字段中输入的制造商ID从订单表中返回结果。订单链接到> OrderItem,然后可以链接到Product。

我已经手动输入了查询,并且可以正常工作,但是在存储过程中设置查询为条件时遇到了麻烦。

这是我手动输入的查询:

SELECT TOP 100 *
FROM [Test].[dbo].[Order] o
LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.[OrderId] = o.[Id]
LEFT JOIN  [Test].[dbo].[Product] p ON p.[Id] = oi.[ProductId]
WHERE p.[ManufacturerId] = 'mid'

这是我的存储过程:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[OrderLoadAllPaged]
    @OrderId INT = 0,
    @CustomerId INT = 0,
    @ProductId INT = 0,
    @WarehouseId INT = 0,
    @BillingCountryId INT = 0,
    @PaymentMethodSystemName NVARCHAR(MAX) = NULL,
    @OrderStatusId INT = 0,
    @PaymentStatusId INT = 0,
    @ShippingStatusId INT = 0,
    @BillingEmail NVARCHAR(MAX) = NULL,
    @BillingFirstName NVARCHAR(MAX) = NULL,
    @BillingLastName NVARCHAR(MAX) = NULL,
    @ManCode NVARCHAR(MAX) = NULL,
    @Current BIT = NULL,
    @ShippingMethod NVARCHAR(MAX) = NULL,
    @CreatedFromUtc DATETIME = NULL,
    @CreatedToUtc DATETIME = NULL,
    @PageIndex INT = 0, 
    @PageSize INT = 2147483644,
    @TotalRecords INT = NULL OUTPUT
AS
BEGIN
    DECLARE @sql NVARCHAR(MAX)

    SET NOCOUNT ON;

    CREATE TABLE #TempTotal (RowNum INT IDENTITY(1,1), id INT);
    CREATE INDEX #IK_temp ON #TempTotal (RowNum);

    INSERT INTO #TempTotal ([id])
        SELECT o.[Id]
        FROM [Test].[dbo].[Order] o WITH (NOLOCK)
        LEFT JOIN [Test].[dbo].[Address] a ON a.Id = o.BillingAddressId 
                                           AND (COALESCE(@BillingEmail, '') <> ''
                                                OR COALESCE(@BillingFirstName, '') <> ''
                                                OR COALESCE(@BillingLastName, '') <> '')
        /* LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.OrderId = o.Id 
                                                 AND (COALESCE(@ManCode,'') <> '')
        LEFT join [Test].[dbo].[Product] p ON p.Id = oi.ProductId 
                                           AND (COALESCE(@ManCode, '') <> '')*/
    WHERE (@BillingEmail IS NULL OR a.[Email] = @BillingEmail)
      AND (@BillingFirstName IS NULL OR a.[FirstName] = @BillingFirstName)
      AND (@BillingLastName IS NULL OR a.[LastName] = @BillingLastName)
      -- AND (@ManCode IS NULL OR p.[ManufacturerId] = @ManCode)


    UNION ALL

    (SELECT * 
     FROM [Test].[dbo].[Product] p
     LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.[OrderId] = o.[Id]
     LEFT JOIN [Test].[dbo].[Product] p ON p.[Id] = oi.[ProductId]
     WHERE (@ManCode IS NULL OR p.[ManufacturerId] = @ManCode))

       AND -- here is error
            o.[Deleted] = 0
       AND (o.[Id] = @OrderId OR @OrderId = 0)
       AND (o.[CustomerId] = @CustomerId OR @CustomerId = 0)
       AND (o.[WarehouseId] = @WarehouseId OR @WarehouseId = 0)
       AND (@PaymentMethodSystemName IS NULL OR o.[PaymentMethodSystemName] = @PaymentMethodSystemName)
       AND (o.[OrderStatusId] = @OrderStatusId OR @OrderStatusId = 0)
       AND (o.[PaymentStatusId] = @PaymentStatusId OR @PaymentStatusId = 0)
       AND (o.[ShippingStatusId] = @ShippingStatusId OR @ShippingStatusId = 0)
       AND ((o.[OrderStatusId] != '40' AND o.[OrderStatusId] != '30' AND ((o.[ShippingStatusId] != '30' OR o.[ShippingStatusId] != '40') AND o.[Printed] = '0' AND (o.[PaymentStatusId] != '30' OR o.[PaymentStatusId] != '35' OR o.[PaymentStatusId]  != '40'))) OR @Current = 0)
       AND o.[CreatedOnUtc] >= ISNULL(@CreatedFromUtc, '1/1/1900')
       AND o.[CreatedOnUtc] < ISNULL(@CreatedToUtc, '1/1/2999')
    ORDER BY 
        o.[CreatedOnUtc] DESC;

    --paging
    DECLARE @PageLowerBound INT 
    SET @PageLowerBound = @PageSize * @PageIndex

    -- Return the paged records
    SELECT 
        [Id], [OrderGuid], [StoreId], [CustomerId],
        [BillingAddressId], [ShippingAddressId], 
        [OrderStatusId], [ShippingStatusId],
        [PaymentStatusId], [PaymentMethodSystemName],
        [TaxRates], [OrderTax], [OrderDiscount], [OrderTotal],
        [ShippingMethod], [CustomValuesXml], [Deleted],
        [CreatedOnUtc], [EditedStatusId],
        [WarehouseId], [PrintedOnUtc]
    FROM
        [Test].[dbo].[Order] ord
    WHERE
        ord.[Id] IN (SELECT id FROM #TempTotal tt)
    ORDER BY 
        ord.[CreatedOnUtc] DESC
        OFFSET @PageLowerBound ROWS FETCH NEXT @PageSize ROWS ONLY;

    --total records
    SELECT @TotalRecords = COUNT(*) FROM #TempTotal;

    DROP TABLE #TempTotal
END

我不确定UNION ALL是否是我所需要的,但我感觉是这样。我也尝试了已被注释掉但没有运气的左联接。

还有这是AND语句中错误的屏幕截图。

enter image description here

有人能在这里帮助我吗?

sql sql-server stored-procedures conditional-statements union-all
2个回答
0
投票
ALTER PROCEDURE [dbo].[OrderLoadAllPaged]
    @OrderId int = 0,
    @CustomerId int = 0,
    @ProductId int = 0,
    @WarehouseId int = 0,
    @BillingCountryId int = 0,
    @PaymentMethodSystemName nvarchar(max) = null,
    @OrderStatusId int = 0,
    @PaymentStatusId int = 0,
    @ShippingStatusId int = 0,
    @BillingEmail nvarchar(max) = null,
    @BillingFirstName nvarchar(max) = null,
    @BillingLastName nvarchar(max) = null,
    @ManCode nvarchar(max) = null,
    @Current bit = null,
    @ShippingMethod nvarchar(max) = null,
    @CreatedFromUtc datetime = null,
    @CreatedToUtc datetime = null,
    @PageIndex int = 0, 
    @PageSize int = 2147483644,
    @TotalRecords int = null OUTPUT
AS
BEGIN
    DECLARE
        @sql nvarchar(max)

    SET NOCOUNT ON;

    create table #TempTotal (RowNum int identity(1,1), id int);
    create index #IK_temp on #TempTotal (RowNum);

    INSERT INTO #TempTotal ([id])
        SELECT o.[Id]
        FROM [Test].[dbo].[Order] o with (NOLOCK)

    LEFT join [Test].[dbo].[Address] a on a.Id = o.BillingAddressId and (
        coalesce(@BillingEmail,'') <> ''
        or coalesce(@BillingFirstName,'') <> ''
        or coalesce(@BillingLastName,'') <> ''
    )
    /*LEFT join [Test].[dbo].[OrderItem] oi on oi.OrderId = o.Id and (
        coalesce(@ManCode,'') <> ''
    )
    LEFT join [Test].[dbo].[Product] p on p.Id = oi.ProductId and (
        coalesce(@ManCode,'') <> ''
    )*/
    WHERE (@BillingEmail IS null OR a.[Email] = @BillingEmail)
    AND (@BillingFirstName IS null OR a.[FirstName] = @BillingFirstName)
    AND (@BillingLastName IS null OR a.[LastName] = @BillingLastName)
    --AND (@ManCode IS null OR p.[ManufacturerId] = @ManCode)


    UNION ALL
    SELECT * FROM
    (
        select * from [Test].[dbo].[Product] p

        LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.[OrderId] = o.[Id]
        LEFT JOIN  [Test].[dbo].[Product] p ON p.[Id] = oi.[ProductId]
        WHERE (@ManCode IS null OR p.[ManufacturerId] = @ManCode)
    )O

    WHERE -- here is error (Here Procdure Can't Findout the object  O) ---So, take 'O' Object Outside........
       o.[Deleted] = 0

    AND (o.[Id] = @OrderId OR @OrderId = 0)

    AND (o.[CustomerId] = @CustomerId OR @CustomerId = 0)

    AND (o.[WarehouseId] = @WarehouseId OR @WarehouseId = 0)

    AND (@PaymentMethodSystemName IS null OR o.[PaymentMethodSystemName] = @PaymentMethodSystemName)

    AND (o.[OrderStatusId] = @OrderStatusId OR @OrderStatusId = 0)
    AND (o.[PaymentStatusId] = @PaymentStatusId OR @PaymentStatusId = 0)
    AND (o.[ShippingStatusId] = @ShippingStatusId OR @ShippingStatusId = 0)

    AND ((o.[OrderStatusId] != '40' AND o.[OrderStatusId] != '30' AND ((o.[ShippingStatusId] != '30' OR o.[ShippingStatusId] != '40') AND o.[Printed] = '0' AND (o.[PaymentStatusId] != '30' OR o.[PaymentStatusId] != '35' OR o.[PaymentStatusId]  != '40'))) OR @Current = 0)

    AND o.[CreatedOnUtc] >= ISNULL(@CreatedFromUtc, '1/1/1900')
    AND o.[CreatedOnUtc] < ISNULL(@CreatedToUtc, '1/1/2999')

    ORDER BY o.[CreatedOnUtc] DESC;

    --paging
    DECLARE @PageLowerBound int
    SET @PageLowerBound = @PageSize * @PageIndex

    -- Return the paged records
    select [Id]
      ,[OrderGuid]
      ,[StoreId]
      ,[CustomerId]
      ,[BillingAddressId]
      ,[ShippingAddressId]
      ,[OrderStatusId]
      ,[ShippingStatusId]
      ,[PaymentStatusId]
      ,[PaymentMethodSystemName]
      ,[TaxRates]
      ,[OrderTax]
      ,[OrderDiscount]
      ,[OrderTotal]
      ,[ShippingMethod]
      ,[CustomValuesXml]
      ,[Deleted]
      ,[CreatedOnUtc]
      ,[EditedStatusId]
      ,[WarehouseId]
      ,[PrintedOnUtc]
    from [Test].[dbo].[Order] ord
    where ord.[Id] in (
      select id
      from #TempTotal tt
    )
    ORDER BY ord.[CreatedOnUtc] DESC
    OFFSET @PageLowerBound ROWS FETCH NEXT @PageSize ROWS ONLY;

    --total records
    select @TotalRecords = count(*) from #TempTotal;

    DROP TABLE #TempTotal
END

注意:-(此处无法找到对象O)---因此,请将“ O”对象带到外面........如果找不到对象(别名)...在某些情况下将无法使用...


0
投票
USE [Test]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[OrderLoadAllPaged]
    @OrderId int = 0,
    @CustomerId int = 0,
    @ProductId int = 0,
    @WarehouseId int = 0,
    @BillingCountryId int = 0,
    @PaymentMethodSystemName nvarchar(max) = null,
    @OrderStatusId int = 0,
    @PaymentStatusId int = 0,
    @ShippingStatusId int = 0,
    @BillingEmail nvarchar(max) = null,
    @BillingFirstName nvarchar(max) = null,
    @BillingLastName nvarchar(max) = null,
    @ManCode nvarchar(max) = null,
    @Current bit = null,
    @ShippingMethod nvarchar(max) = null,
    @CreatedFromUtc datetime = null,
    @CreatedToUtc datetime = null,
    @PageIndex int = 0, 
    @PageSize int = 2147483644,
    @TotalRecords int = null OUTPUT
AS
BEGIN
    DECLARE
        @sql nvarchar(max)

    SET NOCOUNT ON;

    create table #TempTotal (RowNum int identity(1,1), id int);
    create index #IK_temp on #TempTotal (RowNum);

    INSERT INTO #TempTotal ([id])
        SELECT o.[Id]
        FROM [Test].[dbo].[Order] o with (NOLOCK)

    LEFT join [Test].[dbo].[Address] a on a.Id = o.BillingAddressId and (
        coalesce(@BillingEmail,'') <> ''
        or coalesce(@BillingFirstName,'') <> ''
        or coalesce(@BillingLastName,'') <> ''
    )
    /*LEFT join [Test].[dbo].[OrderItem] oi on oi.OrderId = o.Id and (
        coalesce(@ManCode,'') <> ''
    )
    LEFT join [Test].[dbo].[Product] p on p.Id = oi.ProductId and (
        coalesce(@ManCode,'') <> ''
    )*/
    WHERE (@BillingEmail IS null OR a.[Email] = @BillingEmail)
    AND (@BillingFirstName IS null OR a.[FirstName] = @BillingFirstName)
    AND (@BillingLastName IS null OR a.[LastName] = @BillingLastName)
    --AND (@ManCode IS null OR p.[ManufacturerId] = @ManCode)


    UNION ALL
    select oi.[Id] from [Test].[dbo].[Product] p

        LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.[OrderId] = o.[Id]
        LEFT JOIN  [Test].[dbo].[Product] p ON p.[Id] = oi.[ProductId]
        WHERE (@ManCode IS null OR p.[ManufacturerId] = @ManCode)

    AND -- here is error
        o.[Deleted] = 0

    AND (o.[Id] = @OrderId OR @OrderId = 0)

    AND (o.[CustomerId] = @CustomerId OR @CustomerId = 0)

    AND (o.[WarehouseId] = @WarehouseId OR @WarehouseId = 0)

    AND (@PaymentMethodSystemName IS null OR o.[PaymentMethodSystemName] = @PaymentMethodSystemName)

    AND (o.[OrderStatusId] = @OrderStatusId OR @OrderStatusId = 0)
    AND (o.[PaymentStatusId] = @PaymentStatusId OR @PaymentStatusId = 0)
    AND (o.[ShippingStatusId] = @ShippingStatusId OR @ShippingStatusId = 0)

    AND ((o.[OrderStatusId] != '40' AND o.[OrderStatusId] != '30' AND ((o.[ShippingStatusId] != '30' OR o.[ShippingStatusId] != '40') AND o.[Printed] = '0' AND (o.[PaymentStatusId] != '30' OR o.[PaymentStatusId] != '35' OR o.[PaymentStatusId]  != '40'))) OR @Current = 0)

    AND o.[CreatedOnUtc] >= ISNULL(@CreatedFromUtc, '1/1/1900')
    AND o.[CreatedOnUtc] < ISNULL(@CreatedToUtc, '1/1/2999')

    ORDER BY o.[CreatedOnUtc] DESC;

    --paging
    DECLARE @PageLowerBound int
    SET @PageLowerBound = @PageSize * @PageIndex

    -- Return the paged records
    select [Id]
      ,[OrderGuid]
      ,[StoreId]
      ,[CustomerId]
      ,[BillingAddressId]
      ,[ShippingAddressId]
      ,[OrderStatusId]
      ,[ShippingStatusId]
      ,[PaymentStatusId]
      ,[PaymentMethodSystemName]
      ,[TaxRates]
      ,[OrderTax]
      ,[OrderDiscount]
      ,[OrderTotal]
      ,[ShippingMethod]
      ,[CustomValuesXml]
      ,[Deleted]
      ,[CreatedOnUtc]
      ,[EditedStatusId]
      ,[WarehouseId]
      ,[PrintedOnUtc]
    from [Test].[dbo].[Order] ord
    where ord.[Id] in (
      select id
      from #TempTotal tt
    )
    ORDER BY ord.[CreatedOnUtc] DESC
    OFFSET @PageLowerBound ROWS FETCH NEXT @PageSize ROWS ONLY;

    --total records
    select @TotalRecords = count(*) from #TempTotal;

    DROP TABLE #TempTotal
END
© www.soinside.com 2019 - 2024. All rights reserved.