我有一个类似
的程序Procedure P_GENDER_REP
(
l_province IN varchar,
l_district IN varchar,
l_village IN varchar,
l_tribe IN varchar,
l_clan IN varchar,
l_refcursor out sys_refcursor
)
我在这个程序中有一个选择查询
select a.province,a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN,b.cdr_data
from itaukei_data_store b,itaukei_data_store_key a
where a.reference_no = b.reference_no and a.record_no = b.record_no and a.province = l_province
and a.district = l_district and a.village = l_village and a.tribe= l_tribe
and a.clan = l_clan
order by a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN;
现在我需要一个处理给定输入的select查询。例如,如果只给出l_province,我需要忽略动态条件的所有其他。请帮助我。
答案 0 :(得分:1)
通常您可以通过在每个条件中添加OR l_variable IS NULL
来执行此操作:
select a.province,a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN,b.cdr_data
from itaukei_data_store b INNER JOIN itaukei_data_store_key a
ON a.reference_no = b.reference_no
and a.record_no = b.record_no
and a.province = l_province
WHERE l_district IS NULL OR a.district = l_district
and l_village IS NULL OR a.village = l_village
and l_tribe IS NULL OR a.tribe= l_tribe
and l_clan IS NULL OR a.clan = l_clan
order by a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN;
但是,这有时会影响性能。最好为每种组合使用IF。或者,您可以尝试使用支持短路的CASE语句,如下所示:
select a.province,a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN,b.cdr_data
from itaukei_data_store b INNER JOIN itaukei_data_store_key a
ON a.reference_no = b.reference_no
and a.record_no = b.record_no
and a.province = l_province
WHERE a.district = CASE WHEN l_district IS NULL THEN a.district ELSE l_district END
and a.village = CASE WHEN l_village IS NULL THEN a.village ELSE l_village END
and a.tribe = CASE WHEN l_tribe IS NULL THEN a.tribe ELSE l_tribe END
and a.clan = CASE WHEN l_clan IS NULL THEN a.clan ELSE l_clan END
order by a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN;
你有第三种选择。您可以使用COALESCE
代替CASE
,如下所示:
select a.province,a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN,b.cdr_data
from itaukei_data_store b INNER JOIN itaukei_data_store_key a
ON a.reference_no = b.reference_no
and a.record_no = b.record_no
and a.province = l_province
WHERE a.district = COALESCE(l_district, a.district)
and a.village = COALESCE(l_village, a.village)
and a.tribe = COALESCE(l_tribe, a.tribe)
and a.clan = COALESCE(l_clan, a.clan)
order by a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN;
尝试每一个,看看哪个表现更好。顺便说一下,我还将FROM子句从逗号分隔的表列表更改为标准的INNER JOIN。请养成使用JOIN的习惯,因为它现在被认为是最好的parctice"
答案 1 :(得分:0)
给出的例子是SQL Server, 第一种方式,简单如果
Declare @l_province int
Declare @l_district int
Declare @l_village int
If @l_province is not null and @l_district is null and @l_village is null -- Only l_province is given
Begin
select a.province,a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN,b.cdr_data
from itaukei_data_store b,itaukei_data_store_key a
order by a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN;
End
Else
Begin
select a.province,a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN,b.cdr_data
from itaukei_data_store b,itaukei_data_store_key a
where a.reference_no = b.reference_no
and a.record_no = b.record_no
and a.province = l_province
and a.district = l_district
and a.village = l_village
and a.tribe= l_tribe
and a.clan = l_clan
order by a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN;
End
---------------------使用OR,AND的第二种方式
select a.province,a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN,b.cdr_data
from itaukei_data_store b,itaukei_data_store_key a
where (
(
(@l_province is not null and @l_district is null and @l_village is null) -- Only l_province is given
AND
(1=1)
)
OR
(
(@l_province is not null and (@l_district is not null OR @l_village is not null))
AND
(
a.reference_no = b.reference_no
and a.record_no = b.record_no
and a.province = l_province
and a.district = l_district
and a.village = l_village
and a.tribe= l_tribe
and a.clan = l_clan
)
)
OR
(
(@l_province is null)
AND
(
a.reference_no = b.reference_no
and a.record_no = b.record_no
and a.province = l_province
and a.district = l_district
and a.village = l_village
and a.tribe= l_tribe
and a.clan = l_clan
)
)
)
order by a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN;
实际上为了使存储过程变得简单,我建议你带一个应该使用where子句的参数!要计算该变量,您需要在代码后面或存储过程开始时编写一些代码。它会让生活变得轻松。
答案 2 :(得分:0)
只是为了添加另一个黑客。
如果您对每个列都没有类似的值,则可以使用coalesce
select a.province,a.district,a.village,a.tribe,a.clan,b.cdr_data
from itaukei_data_store b,itaukei_data_store_key a
where a.reference_no = b.reference_no
and a.record_no = b.record_no
and coalesce(a.province,a.district,a.village,a.tribe,a.clan) =
coalesce(l_province,l_district,l_village,l_tribe,l_clan)
order by a.district,a.village,a.tribe,a.clan;
Coalesce返回列表中的第一个not null值
答案 3 :(得分:0)
你可以调整这些参数,这样当它们被设置时,它们就会被使用,否则就会得到比较表中的匹配值..应该具有预期的效果:
select a.province,a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN,b.cdr_data
from itaukei_data_store b,itaukei_data_store_key a
where a.reference_no = b.reference_no
and a.record_no = b.record_no
and a.province = nvl(l_province, a.province)
and a.district = nvl(l_district, a.district)
and a.village = nvl(l_village, a.village)
and a.tribe = nvl(l_tribe, a.tribe)
and a.clan = nvl(l_clan, a.clan)
order by a.DISTRICT,a.VILLAGE,a.TRIBE,a.CLAN;