如何在SQL Server中的条件检查中重用子查询?

时间:2017-03-21 07:27:43

标签: c# sql-server

我想从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之后查询与上面的子查询相同。提前谢谢。

2 个答案:

答案 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 + '%';

我发现联盟在某些情况下是有益的,因为你正在帮助优化器拆分他的查找逻辑。