【问题标题】:Search query on multiple columns of a table?在表的多个列上搜索查询?
【发布时间】:2014-04-28 11:22:27
【问题描述】:

我们在这样的表上实现搜索

   create proc prcSearchMember 
(
@UserId uniqueidentifier,
@MemberFirstName varchar(20),
@MemberMiddleName varchar(20),
@MemberLastName varchar(20),
@FamilyHeadName varchar(50),
@FatherName varchar(50),
@MotherName varchar(50),
@DOB datetime,
@GotraID int,
@SectID int,
@BloodGroupID int,
@EducationLevelID int, 
@EducationFieldID int,
@HouseNumber varchar(20),
@StreetName varchar(50),
@Area varchar(50),
@LandMark varchar(50),
@StateID int,
@CountryID int,
@CityID int, 
@PhoneNumber varchar(15),
@EmailAddress varchar(50),
@MaritalStatus varchar(20),
@OccupationTypeID int,
@Gender varchar(10),
@IsSubmit bit
)
as 
if(@MemberFirstName is not null )
 Begin  
Select MemberFirstName,UserId from  MemberInfo
 where MemberFirstName  like  @MemberFirstName
 end
else if (@MemberMiddleName is not null )
Begin  
Select MemberFirstName,UserId from  MemberInfo 
where MemberMiddleName like @MemberMiddleName
end
else if (@MemberMiddleName is not null ) 
Begin    
Select MemberFirstName,UserId from  MemberInfo   where   MemberLastName  like @MemberLastName
end
else if (@MemberLastName is not null ) 
Begin   
Select MemberFirstName,UserId from   MemberInfo   where FamilyHeadName  like @MemberLastName  
end
else if (@MemberLastName is not null ) 
Begin   
Select MemberFirstName,UserId from   MemberInfo   where  FatherName  like @FatherName 
end
else if (@MemberLastName is not null ) 
Begin   
Select MemberFirstName,UserId from   MemberInfo   where MotherName  like @MotherName 
end
else if (@DOB is not null ) Begin   
Select MemberFirstName,UserId from   MemberInfo   where DOB like @DOB
end
else if (@GotraID is not null ) 
Begin    
Select MemberFirstName,UserId from   MemberInfo   where  GotraID like @GotraID
end
else if (@SectID is not null ) Begin    
Select MemberFirstName,UserId from   MemberInfo   where SectID=@SectID
end
else if (@BloodGroupID is not null ) Begin    
Select MemberFirstName,UserId from   MemberInfo   where BloodGroupID like @BloodGroupID  
end
else if (@EducationLevelID is not null ) Begin    
Select MemberFirstName,UserId from   MemberInfo   where EducationLevelID=@EducationLevelID 
end
else if (@EducationFieldID is not null ) Begin    
Select  MemberFirstName,UserId from   MemberInfo   where EducationFieldID like EducationFieldID
end
else if (@HouseNumber is not null ) Begin    
Select MemberFirstName,UserId from   MemberInfo   where HouseNumber like @HouseNumber  
end
else if (@StreetName is not null ) Begin    
Select MemberFirstName,UserId from   MemberInfo   where StreetName like @StreetName  
end
else if (@Area is not null ) Begin    
Select MemberFirstName,UserId from   MemberInfo   where Area like @Area  
end
else if (@LandMark is not null ) Begin    
Select MemberFirstName,UserId from   MemberInfo   where LandMark like @LandMark  
end
else if (@CountryID is not null ) Begin    
Select MemberFirstName,UserId from MemberInfo where CountryID like @CountryID
end
else if (@StateID is not null ) 
Begin  
select MemberFirstName,UserId from   MemberInfo   where StateID like @StateID 
end
else if (@CityID is not null ) Begin    
Select MemberFirstName,UserId from   MemberInfo   where CityID like CityID 
end
else if (@OccupationTypeID is not null ) Begin    
Select  MemberFirstName,UserId from   MemberInfo   where  OccupationTypeID like @OccupationTypeID 
end
else if (@PhoneNumber is not null ) Begin    
Select  MemberFirstName,UserId from   MemberInfo   where  PhoneNumber like @PhoneNumber 
end
else if (@EmailAddress is not null ) 
Begin     
Select MemberFirstName,UserId from   MemberInfo   where EmailAddress  like @EmailAddress 
 end
else if (@MaritalStatus is not null )
 Begin     
Select MemberFirstName,UserId from   MemberInfo   where MaritalStatus  like @MaritalStatus 
 end
else if (@Gender is not null ) 
Begin     
Select MemberFirstName,UserId from  MemberInfo   where Gender like @Gender 
end
else if (@UserId is not null ) Begin    
Select MemberFirstName,UserId from  MemberInfo   where  UserId like @UserId

这些都是单表的列

所以如果有什么方法可以这样实现搜索查询

foreach (column_name in INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'YourTableName')
   select primary_key_coumn 
   from table_name 
   where column_name like @column_name

其中@column_name 是特定column 的值

【问题讨论】:

  • 这是什么意思。如果除 Gender 之外的所有内容都为 null,并且您传入 Male,您是否只想获取 X 多行,所有行都包含文本 Male?这就是这里的输出。
  • 抱歉查询错误我已经编辑了@Paddy
  • 是否要在所有表中搜索列和值(如column = value)?
  • 是否有机会尝试一次过滤多个列?
  • @Bharadwaj 是的

标签: sql sql-server-2008 search


【解决方案1】:

试试下面的,

DECLARE @ColName varchar(126) = 'col_name'
DECLARE @ColVal varchar(64) = 'col_val'

DECLARE @SQL AS nvarchar(MAX)
SET @SQL = ''

SELECT @SQL = @SQL + 'SELECT * FROM ' + IST.TABLE_SCHEMA + '.' + IST.TABLE_NAME 
                       +' where '+ @ColName +' = '''+ @ColVal +''' ' + CHAR(13)
FROM 
    INFORMATION_SCHEMA.TABLES IST
    INNER JOIN INFORMATION_SCHEMA.COLUMNS ISC ON IST.TABLE_NAME = ISC.TABLE_NAME
WHERE
    ISC.COLUMN_NAME = @ColName

EXEC (@SQL)

【讨论】:

  • 这仅适用于文本列。此外,请使用系统目录视图,因为 sysobjects 和 syscolumns 在过去 9 年中已被弃用,并且很可能很快就会消失。
  • @StevePettifer 感谢您指出错误。我希望INFORMATION_SCHEMA 仍然有效。
  • 是的,我相信它是 ANSI 92 SQL 标准的一部分。这确实使它更具可移植性,但对于 SQL Server,首选方法是使用系统目录视图,因为 INFORMATION_SCHEMA 非常有限,因为它应该得到普遍支持。
  • “没有完美的解决方案”是什么意思?您不需要需要 INFORMATION_SCHEMA,因为系统目录视图提供了它所做的任何事情以及除此之外的更多内容。评论格式会杀死这一点,但没关系:DECLARE @ColName SYSNAME DECLARE @ColVal NVARCHAR(100) DECLARE @SQL NVARCHAR(1000) SELECT @SQL = 'SELECT * FROM ' + QUOTENAME(SCHEMA_NAME([schema_id])) + '.' + QUOTENAME(t.[name]) + ' WHERE ' + @ColName + ' = ''' + @ColVal + ''';' FROM sys.tables t INNER JOIN sys.columns c ON c.[object_id] = t.[object_id] WHERE c.[name] = @ColName EXECUTE sp_executesql @SQL
  • 此外,如果您在 SQL Server 中处理对象名称,请使用 SYSNAME 作为类型 - 它是 NVARCHAR(128) 的同义词,它是对象名称的 SQL 标准大小和类型(在Oracle,他们有“部分支持”——即只有 32 个字符)。
【解决方案2】:

我不确定你想要达到什么目的。你是在问“有没有更好的方法来编写这个搜索?”。如果是这样,那么是的,绝对的。据我所见,每个IF 分支都选择相同的列,因此如果您确保所有存储的过程参数在声明中默认为NULL,那么您可以执行以下操作:

SELECT MemberFirstName, UserId 
FROM  MemberInfo
WHERE (MemberFirstName  LIKE @MemberFirstName OR @MemberFirstName IS NULL)
AND (MemberMiddleName LIKE @MemberMiddleName OR @MemberMiddleName IS NULL)
AND (MemberLastName  LIKE @MemberLastName OR @MemberLastName  IS NULL)
AND --You get the picture by now. Keep adding your conditions here.

优化器足够智能,不会打扰任何计算结果为 NULL 的条件(这就是为什么您必须确保参数默认为 NULL)。

请注意,您的许多分支将永远不会执行,因为您有:

else if (@MemberLastName is not null ) 
Begin   
Select MemberFirstName,UserId from   MemberInfo   where FamilyHeadName  like @MemberLastName  
end
else if (@MemberLastName is not null ) 
Begin   
Select MemberFirstName,UserId from   MemberInfo   where  FatherName  like @FatherName 
end
else if (@MemberLastName is not null ) 
Begin   
Select MemberFirstName,UserId from   MemberInfo   where MotherName  like @MotherName 
end

只有第一个分支会被执行。

我不确定您为什么要询问主键列以及为什么要迭代表中的列以获取主键列?在单个表中,该表的主键列对于您检查的该表中的每个列名都是相同的。这对你有什么影响?您要解决的实际问题是什么?还值得指出的是,从 SQL Server 2005 开始,建议您使用系统目录视图而不是 INFORMATION_SCHEMA,它们使用起来非常简单。

【讨论】:

    【解决方案3】:

    您可以让您的条件退回到重言式。
    重言式的条件永远不会被评估,所以像

    SELECT MemberFirstName
         , UserId 
    FROM   MemberInfo
    WHERE  MemberFirstName like MemberFirstName
    

    等价于

    SELECT MemberFirstName
         , UserId 
    FROM   MemberInfo
    

    当参数为NULL 时,可以使用COALESCEISNULL 更改查询,使条件变为重言式。

    对于前几个条件,它类似于

    SELECT MemberFirstName, UserId 
    FROM   MemberInfo
    WHERE  MemberFirstName  like COALESCE(@MemberFirstName, MemberFirstName)
      AND  MemberMiddleName like COALESCE(@MemberMiddleName, MemberMiddleName)
      AND  MemberLastName   like COALESCE(@MemberLastName, MemberLastName)
      AND  FamilyHeadName   like COALESCE(@FamilyHeadName, FamilyHeadName)
    

    【讨论】:

      【解决方案4】:

      您可以根据您的搜索参数构建动态 SQL。

      请参阅以下链接中的示例 2.0:Building Dynamic SQL in Stored Procedure

      【讨论】:

        猜你喜欢
        • 2016-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-01
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        相关资源
        最近更新 更多