的Bonjour!
因此,在存储过程中,我想做一个由参数决定的条件联合。 我怎么能这样做?
这是我的“无效”程序:
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 \ test = a -1我想没有UNION。
我用动态varchar查询做了这个,最后我用exec执行查询。但它显然效率较低,你可以使用动态查询进行SQL注入(适用于asp.net应用程序)。我决定更改所有存储过程
在IF子句中不可能建立联合吗?
感谢所有答案,无例外。
答案 0 :(得分:22)
通常做一个基于案例的联合,你转换伪
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
)
答案 1 :(得分:1)
您可以使用where
子句选择联合的任一端:
select col1, col2 from TableA where @Param = 1
UNION ALL
select col1, col2 from TableB where @Param = 2
在您的示例中,您可以完全省略IF
语句,因为没有地址的ID_ADDRESS为-1。
答案 2 :(得分:1)
难道你不能像这样重写你的查询:
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,那么它将返回该行以及第一个查询中返回的行。
答案 3 :(得分:0)
我很好奇是不能使用一个选择然后使用两个where语句但是将它们分开或者像
一样 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