首页 > 解决方案 > 使用动态 SQL 在一个参数中执行多列通配符搜索

问题描述

我的应用程序只有街道号码和街道名称字段。我需要在查询中将街道名称和单位类型声明为一个参数字段。我需要按任何值执行通配符搜索(在街道名称字段上)并返回以下结果。可能的搜索:

Street Number: 1234
Street Name: 
OR
Street Number: 1234
Street Name: Lakeshore SE
OR
Street Number:
Street Name: SE
OR
Street Number: 
Street Name: Lake DR SE

以下是表格结果:

+-----------------------------------+-------------------+-----------+
|               STREET_NUMBER       |    STREET_NAME    | UNIT_TYPE |
+-----------------------------------+-------------------+-----------+
|                   1234            |    LAKESHORE DR   |    SE     |
+-----------------------------------+-------------------+-----------+

这是我的存储过程:

@Street varchar (100) = NULL
,@StreetNumber varchar (100) = NULL

AS
BEGIN
SET NOCOUNT ON;

DECLARE @sql nvarchar(max) = N'
SELECT *
FROM ADDRESS_DETAIL
WHERE 1 = 1'

    + CASE WHEN @Street IS NOT NULL THEN
    N' AND STREET_NAME + UNIT_TYPE LIKE ''%'' + @Street + ''%'''  ELSE N'' END
    + CASE WHEN @StreetNumber IS NOT NULL THEN
    N' AND STREET_NUMBER LIKE @StreetNumber' ELSE N'' END

DECLARE @params nvarchar(max) = N'
@Street varchar (60)
,@StreetNumber varchar (60)';

PRINT @sql;

EXEC sys.sp_executesql @sql, @params, 
@Street,
@StreetNumber;

END

标签: sqlsql-serverstored-proceduresdynamic-sql

解决方案


参数化动态 sql 的主要荣誉。这不是我看到大多数人做的事情。但我认为您在这里不需要动态 sql。我有点担心这里的主要通配符,因为它使查询不可分割。但这对于动态 sql 是否正确。

这是编写此过程的另一种方法,可能更简单一些。

create procedure YourProc
(
    @Street varchar (100) = NULL
    ,@StreetNumber varchar (100) = NULL
) AS
BEGIN
    SET NOCOUNT ON;

    SELECT *
    FROM ADDRESS_DETAIL
    WHERE 
    (
        STREET_NAME + UNIT_TYPE LIKE '%' + @Street + '%'
        OR
        @Street IS NULL
    )
    AND
    (
        STREET_NUMBER LIKE '%' + @StreetNumber + '%'
        OR
        @StreetNumber IS NULL
    )
END

我的猜测是你需要将第一个谓词更改为这样的东西。

@Street like '%' + STREET_NAME + '%' + UNIT_TYPE + '%'

另一个想法...您可以用通配符替换所有空格,以消除导致问题的多个空格。

where STREET_NAME + UNIT_TYPE like replace('@STREET', ' ', '%')

推荐阅读