我想从SQL Server 2012中检索结果。但是为了检查条件我重写了相同的子查询。是否有任何想法只使用子查询并检索结果?
我的查询:
sql = "SELECT customer_id,ISNULL(first_name, '') + ' ' + ISNULL(middle_name, ' ') + ' ' + ISNULL(last_name, ' ') AS 'Customer_name', (ISNULL(city, '') + ',' + ISNULL(district, ' ') + ',' + ISNULL(zone, ' ')) as 'Location' FROM customer_detail WHERE 1=1";
if(location != "")
{
sql += " AND (ISNULL(city, '') + ',' + ISNULL(district, ' ') + ',' + ISNULL(zone, ' ')) LIKE '%" + location + "%'"";
}
在AND之后查询与上面的子查询相同。提前谢谢。
答案 0 :(得分:2)
对于子查询而言,您看起来并不像user defined function (UDF)那样以更漂亮的方式合并3个文本列。
如果您不想使用UDF,那么您可以使用Common Table Expressions (CTE)只写一次表达式。
使用CTE还可以将重用的块封装在查询内部,而在执行查询之前需要将UDF添加到数据库中。根据可重用性需求,这可能是也可能不是理想的事情。
CTE解决方案将遵循以下方针:
WITH CTE (Id, [Name], [Location]) as
(
SELECT customer_id,
ISNULL(first_name, '') + ' ' + ISNULL(middle_name, ' ') + ' ' + ISNULL(last_name, ' '),
ISNULL(city, '') + ',' + ISNULL(district, ' ') + ',' +ISNULL(zone, ' ')
FROM customer_detail
)
select *
from CTE
where 1=1
AND [Location] LIKE '%' + @location + '%'
此外,通常您可以期望CTE通常比UDF更好地执行,因为查询优化器可以修改计划以匹配特定的查询需求。
答案 1 :(得分:0)
我会使用可重复使用的视图和存储过程进行实际搜索。
create view vCustomerDetail
as
select [customer_id]
, isnull([first_name] + ' ', '') + isnull([middle_name] + ' ', '') + isnull([last_name], '') as [Customer_name]
, isnull([city] + ', ', '') + isnull([district] + ', ', '') + isnull([zone], '') as [Location]
from [customer_detail]
go
create proc pCustomerDetailByLocation
(
@location nvarchar(200) = ''
)
as
begin
set nocount on;
select *
from [vCustomerDetail]
where [Location] = ''
union all
select *
from [vCustomerDetail]
where [Location] like '%' + @location + '%';
end
go
您可以使用代码调用存储过程并传递参数中的位置。这样,您可以阻止SQL注入,并且还可以使用比ad-hoc查询更好的执行计划缓存。
你可以使用像我在我的例子中所做的那样的联合,或者将它与OR语句结合起来,如下所示:
where [Location] = '' or [Location] like '%' + @location + '%';
我发现联盟在某些情况下是有益的,因为你正在帮助优化器拆分他的查找逻辑。