存储过程中的条件 UNION

发布于 2024-10-12 19:53:09 字数 1143 浏览 2 评论 0原文

你好!

因此,在存储过程中,我想执行由参数决定的条件并集。 我怎样才能做到这一点?

这是我的“不起作用”程序:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


CREATE PROCEDURE [dbo].[spp_GetAdressesList]

    @OnlyLinked   bit         = 1,    
    @ObligedId    int         = -1 
AS 
BEGIN

    SELECT 
       [ID_ADRESS]
      ,[ID_ENT]
      ,[VOI_ADRESS]
      ,[NUM_ADRESS]
      ,[BTE_ADRESS]
      ,[CP_ADRESS]
      ,[VIL_ADRESS]

    FROM [ADRESSES]
    WHERE  
    (

        (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')
        AND
        (@OnlyLinked = 0 OR ID_ENT is not null)

    )

    IF (@ObligedId != -1)
    BEGIN
        UNION
            SELECT 
               [ID_ADRESS]
              ,[ID_ENT]
              ,[VOI_ADRESS]
              ,[NUM_ADRESS]
              ,[BTE_ADRESS]
              ,[CP_ADRESS]
              ,[VIL_ADRESS]

            FROM [ADRESSES]
            WHERE  
            ID_ADRESS = @ObligedId
    END

END

因此,如果 @ObligedId est = a -1 我希望没有 UNION。

我用动态 varchar 查询做了这个,最后我用 exec 执行查询。但它显然效率较低,您可以使用动态查询进行sql注入(适用于asp.net应用程序)。我决定更改所有存储过程

不可能在 IF 子句中进行并集吗?

感谢所有答案,无一例外。

Bonjour!

So, in a stored procedure I would like to do a conditional union decided by a parameter.
How can I do that?

Here is my "doesn't work" procedure :

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


CREATE PROCEDURE [dbo].[spp_GetAdressesList]

    @OnlyLinked   bit         = 1,    
    @ObligedId    int         = -1 
AS 
BEGIN

    SELECT 
       [ID_ADRESS]
      ,[ID_ENT]
      ,[VOI_ADRESS]
      ,[NUM_ADRESS]
      ,[BTE_ADRESS]
      ,[CP_ADRESS]
      ,[VIL_ADRESS]

    FROM [ADRESSES]
    WHERE  
    (

        (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')
        AND
        (@OnlyLinked = 0 OR ID_ENT is not null)

    )

    IF (@ObligedId != -1)
    BEGIN
        UNION
            SELECT 
               [ID_ADRESS]
              ,[ID_ENT]
              ,[VOI_ADRESS]
              ,[NUM_ADRESS]
              ,[BTE_ADRESS]
              ,[CP_ADRESS]
              ,[VIL_ADRESS]

            FROM [ADRESSES]
            WHERE  
            ID_ADRESS = @ObligedId
    END

END

So if @ObligedId est = a -1 I would like to doesn't have the UNION.

I made this with a dynamic varchar query, at the end I was executing the query with an exec. But it's apparently less efficient and you can make sql injection (It is for asp.net application) with dynamic queries. I decided to change all my stored procedures

It's not possible to do an union in a IF clause?

Thanks for all answers without exceptions..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一桥轻雨一伞开 2024-10-19 19:53:09

通常,要进行基于案例的联合,您会将伪转换

select 1 AS A
IF @b!=-1 then
    union all
    select 2 as B
END IF

select 1 AS A
    union all
    select 2 as B WHERE @b!=-1  -- the condition covers the entire select
             -- because it is a variable test, SQL Server does it first and
             -- aborts the entire part of the union if not true

对于您的查询,这将变为

SELECT 
   [ID_ADRESS],[ID_ENT],[VOI_ADRESS],[NUM_ADRESS],[BTE_ADRESS]
  ,[CP_ADRESS],[VIL_ADRESS]
FROM [ADRESSES]
WHERE  
(
    (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')
    AND
    (@OnlyLinked = 0 OR ID_ENT is not null)
)
    UNION
        SELECT 
           [ID_ADRESS],[ID_ENT],[VOI_ADRESS],[NUM_ADRESS],[BTE_ADRESS]
          ,[CP_ADRESS],[VIL_ADRESS]
        FROM [ADRESSES]
        WHERE  
        ID_ADRESS = @ObligedId
        AND (@ObligedId != -1)

但是,由于在此特定查询中,数据来自同一个表,只是不同的过滤器,因此您将使用 OR 过滤器。 注意: 如果您使用过 UNION ALL,则无法以这种方式减少它,因为 UNION ALL 可能会保留重复项。对于 UNION(无论如何都会删除重复项),OR 缩减效果很好

SELECT 
   [ID_ADRESS],[ID_ENT],[VOI_ADRESS],[NUM_ADRESS],[BTE_ADRESS]
  ,[CP_ADRESS],[VIL_ADRESS]
FROM [ADRESSES]
WHERE  
(
    (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')
    AND
    (@OnlyLinked = 0 OR ID_ENT is not null)
)
OR
(
    ID_ADRESS = @ObligedId
    AND (@ObligedId != -1)   -- include this
)

Normally to do a case based union, you transform the pseudo

select 1 AS A
IF @b!=-1 then
    union all
    select 2 as B
END IF

into

select 1 AS A
    union all
    select 2 as B WHERE @b!=-1  -- the condition covers the entire select
             -- because it is a variable test, SQL Server does it first and
             -- aborts the entire part of the union if not true

For your query, that becomes

SELECT 
   [ID_ADRESS],[ID_ENT],[VOI_ADRESS],[NUM_ADRESS],[BTE_ADRESS]
  ,[CP_ADRESS],[VIL_ADRESS]
FROM [ADRESSES]
WHERE  
(
    (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')
    AND
    (@OnlyLinked = 0 OR ID_ENT is not null)
)
    UNION
        SELECT 
           [ID_ADRESS],[ID_ENT],[VOI_ADRESS],[NUM_ADRESS],[BTE_ADRESS]
          ,[CP_ADRESS],[VIL_ADRESS]
        FROM [ADRESSES]
        WHERE  
        ID_ADRESS = @ObligedId
        AND (@ObligedId != -1)

However, since in this specific query, the data is from the same table just different filters, you would OR the filters instead. Note: if you had used UNION ALL, it can not be reduced this way because of possible duplicates that UNION ALL preserves. For UNION (which removes duplicates anyway), the OR reduction works just fine

SELECT 
   [ID_ADRESS],[ID_ENT],[VOI_ADRESS],[NUM_ADRESS],[BTE_ADRESS]
  ,[CP_ADRESS],[VIL_ADRESS]
FROM [ADRESSES]
WHERE  
(
    (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')
    AND
    (@OnlyLinked = 0 OR ID_ENT is not null)
)
OR
(
    ID_ADRESS = @ObligedId
    AND (@ObligedId != -1)   -- include this
)
飘落散花 2024-10-19 19:53:09

您可以使用 where 子句来选择联合的任一端:

select col1, col2 from TableA where @Param = 1
UNION ALL
select col1, col2 from TableB where @Param = 2

在您的示例中,您可以完全省略 IF 语句,因为没有地址的 ID_ADDRESS 为 -1 。

You could use a where clause to choose either end of the union:

select col1, col2 from TableA where @Param = 1
UNION ALL
select col1, col2 from TableB where @Param = 2

In your example, you could omit the IF statement entirely, since no address will have an ID_ADDRESS of -1.

向日葵 2024-10-19 19:53:09

难道你不能像这样重写你的查询吗:

SELECT 
   [ID_ADRESS]
  ,[ID_ENT]
  ,[VOI_ADRESS]
  ,[NUM_ADRESS]
  ,[BTE_ADRESS]
  ,[CP_ADRESS]
  ,[VIL_ADRESS]

FROM [ADRESSES]
WHERE  
(

    (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')
    AND
    (@OnlyLinked = 0 OR ID_ENT is not null)

)
Or ID_ADRESS = @ObligedId

如果@obligedid等于-1,它将找不到ID,并且不会返回该行。如果它是有效的 ID,那么它将返回该行以及第一个查询中返回的行。

Couldn't you just rewrite your query like this:

SELECT 
   [ID_ADRESS]
  ,[ID_ENT]
  ,[VOI_ADRESS]
  ,[NUM_ADRESS]
  ,[BTE_ADRESS]
  ,[CP_ADRESS]
  ,[VIL_ADRESS]

FROM [ADRESSES]
WHERE  
(

    (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')
    AND
    (@OnlyLinked = 0 OR ID_ENT is not null)

)
Or ID_ADRESS = @ObligedId

If @obligedid is equal to -1 it won't find the Id and there for won't return the row. If it is valid id then it will return the row along with the rows returned in the first query.

她比我温柔 2024-10-19 19:53:09

我很好奇使用一个 select 然后使用两个 where 语句但用 or 分隔它们是否行不通

 SELECT [ID_ADRESS],
       [ID_ENT],
       [VOI_ADRESS],
       [NUM_ADRESS],
       [BTE_ADRESS],
       [CP_ADRESS],
       [VIL_ADRESS]      
FROM [ADRESSES]     
WHERE       
(          
  (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')         
AND         
  (@OnlyLinked = 0 OR ID_ENT is not null)      
) OR ID_ADRESS =-1

i'm curious would it not work to use one select and then use the two where statements but seperate them by an or like

 SELECT [ID_ADRESS],
       [ID_ENT],
       [VOI_ADRESS],
       [NUM_ADRESS],
       [BTE_ADRESS],
       [CP_ADRESS],
       [VIL_ADRESS]      
FROM [ADRESSES]     
WHERE       
(          
  (VIL_ADRESS != 'NC' AND VIL_ADRESS != '--')         
AND         
  (@OnlyLinked = 0 OR ID_ENT is not null)      
) OR ID_ADRESS =-1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文