使用多个关键字搜索sql server表的多个字段

时间:2013-03-05 15:09:00

标签: sql-server xquery

我得到了net的帮助,它指示如何针对多个关键字搜索sql server表的多个字段。

链接网址为http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=103033 并且它们的脚本用于针对多个关键字搜索sql server表的多个字段,如下所示。

select * from YourTable
WHERE PATINDEX('%text1%',COALESCE(field1,'') + '|' + COALESCE(field2,'') + '|'+ COALESCE(field3,'')+ '|' + COALESCE(field4,'')+ '|' + COALESCE(field5,'')+ '|' + COALESCE(field6,'')+ '|' + COALESCE(field7,'') + '|'+ COALESCE(field8,'') + '|'+ COALESCE(field9,''))>0
AND
 PATINDEX('%text2%',COALESCE(field1,'') + '|' + COALESCE(field2,'') + '|'+ COALESCE(field3,'')+ '|' + COALESCE(field4,'')+ '|' + COALESCE(field5,'')+ '|' + COALESCE(field6,'')+ '|' + COALESCE(field7,'') + '|'+ COALESCE(field8,'') + '|'+ COALESCE(field9,''))>0

我不确定上述脚本是否有效。

在我们的例子中,我必须动态地在字符串中开发上述查询。这是我的脚本,它给出了编译错误,我无法弄清楚为什么会出现错误。 这是我的剧本......请看一下。

ALTER PROC usp_SearchData
(
    @FilterXML as XML 
)
AS
BEGIN
    DECLARE @SQL VARCHAR(MAX)
    DECLARE @Main_minID int, @Main_maxID int
    DECLARE @Sub_minID int, @Sub_maxID int
    DECLARE @Main_Col VARCHAR(MAX)
    DECLARE @Sub_Col VARCHAR(MAX)

    CREATE TABLE #SearchFilter
    (
        ID integer identity,
        FilterName varchar(max)
    )

    INSERT INTO #SearchFilter
    SELECT 
        x.y.value('text()[1]', 'varchar(max)') 
    FROM @FilterXML.nodes('root/row') x(y)

    SET @SQL=''
    SET @SQL='SELECT EmailID,[Name],PhoneNo,CurrentLocation as [Current Location]'
    SET @SQL=@SQL+',PreferredWorkLocation as [Preferred Work Location]'
    SET @SQL=@SQL+',JobTypeName as [Role Appling For],AdvertType as [Aware From] '
    SET @SQL=@SQL+'from vwSearchData WHERE '

    SELECT @Main_minID = MIN(ID), @Main_maxID= MAX(ID)
    FROM #SearchFilter

    WHILE @Main_minID <= @Main_maxID
    BEGIN
        SELECT @Main_Col = FilterName FROM #SearchFilter WHERE ID = @Main_minID
        BEGIN
            SET @SQL=@SQL+'PATINDEX('''% + @Main_Col + '%'''
            SELECT @Sub_minID = MIN(ID), @Sub_maxID= MAX(ID) FROM SearchColumns
            WHILE @Sub_minID <= @Sub_maxID
            BEGIN
                SELECT @Sub_Col = FilterName FROM SearchColumns WHERE ID = @Sub_minID
                SET @SQL=@SQL+',COALESCE('+@Sub_Col+','''')| '
                SET @Sub_minID = @Sub_minID + 1
            END
            SET @SQL=SUBSTRING(@SQL, 1, LEN(@SQL)-2) + ')>0 AND '
        END
        SET @SQL=SUBSTRING(@SQL, 1, LEN(@SQL)-5)
        SET @Main_minID = @Main_minID + 1
    END

    IF OBJECT_ID('tempdb..#SearchFilter') IS NOT NULL
    BEGIN
        DROP TABLE #SearchFilter
    END
    PRINT @SQL
END

1)告诉我为什么我会收到错误 2)如何在字符串中动态开发整个PATINDEX语句。 3)只是告诉上面的PATINDEX状态确实适用于多个字段搜索多个关键字

请给我最好的指导,以实现我的工作。感谢

MY Modified script

USE [MyDB]
GO
/****** Object:  StoredProcedure [dbo].[searchTable]    Script Date: 03/05/2013 11:17:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--ALTER proc [dbo].[searchTable]
--AS
BEGIN
    --DECLARE @FilterXML as XML 
    DECLARE @SQL VARCHAR(MAX)
    DECLARE @Main_minID int, @Main_maxID int
    DECLARE @Sub_minID int, @Sub_maxID int
    DECLARE @Main_Col VARCHAR(MAX)
    DECLARE @Sub_Col VARCHAR(MAX)

    CREATE TABLE #SearchFilter
    (
        ID integer identity,
        FilterName varchar(max)
    )

DECLARE @FilterXML XML 
SET @FilterXML = '<root>
  <row>France</row>
  <row>CSR</row>
  <row>technician</row>
</root>'

    INSERT INTO #SearchFilter
    SELECT 
        x.y.value('text()[1]', 'varchar(max)') 
    FROM @FilterXML.nodes('root/row') x(y)

    SET @SQL=''
    --SET @SQL='SELECT EmailID,[Name],PhoneNo,CurrentLocation as [Current Location]'
    --SET @SQL=@SQL+',PreferredWorkLocation as [Preferred Work Location]'
    --SET @SQL=@SQL+',JobTypeName as [Role Appling For],AdvertType as [Aware From] '
    --SET @SQL=@SQL+'from vwSearchData WHERE '

    SELECT @Main_minID = MIN(ID), @Main_maxID= MAX(ID)
    FROM #SearchFilter

    WHILE @Main_minID <= @Main_maxID
    BEGIN
        SELECT @Main_Col = FilterName FROM #SearchFilter WHERE ID = @Main_minID
        BEGIN
            SET @SQL=@SQL+'PATINDEX(''%' + @Main_Col + '%'''
            --PATINDEX('%France%'PATINDEX('%CSR%'PATINDEX('%technician%'
            SELECT @Sub_minID = MIN(ID), @Sub_maxID= MAX(ID) FROM SearchColumns
            WHILE @Sub_minID <= @Sub_maxID
            BEGIN
                SELECT @Sub_Col = FilterName FROM SearchColumns WHERE ID = @Sub_minID
                SET @SQL=@SQL+',COALESCE('+@Sub_Col+','''')| '
                SET @Sub_minID = @Sub_minID + 1
            END
            SET @SQL=SUBSTRING(@SQL, 1, LEN(@SQL)-1) + ')>0 AND ' + CHAR(13);
        END

        SET @Main_minID = @Main_minID + 1
    END
    SET @SQL=SUBSTRING(@SQL, 1, LEN(@SQL)-5)

    IF OBJECT_ID('tempdb..#SearchFilter') IS NOT NULL
    BEGIN
        DROP TABLE #SearchFilter
    END
    PRINT @SQL
END

这样我终于解决了它

    ALTER PROC [dbo].[SearchCVData]
    (
        @FilterXML as XML 
    )
    AS
    BEGIN
        DECLARE @SQL VARCHAR(MAX)
        DECLARE @Main_minID int, @Main_maxID int
        DECLARE @Sub_minID int, @Sub_maxID int
        DECLARE @Main_Col VARCHAR(MAX)
        DECLARE @Sub_Col VARCHAR(MAX)

        CREATE TABLE #SearchFilter
        (
            ID integer identity,
            FilterName varchar(max)
        )

        INSERT INTO #SearchFilter
        SELECT 
            x.y.value('text()[1]', 'varchar(max)') 
        FROM @FilterXML.nodes('Filter/value') x(y)

        SET @SQL=''
        SET @SQL='SELECT EmailID,[Name],PhoneNo,CurrentLocation as [Current Location]'  + CHAR(13);
        SET @SQL=@SQL+',PreferredWorkLocation as [Preferred Work Location]'             + CHAR(13);
        SET @SQL=@SQL+',JobTypeName as [Role Appling For],AdvertType as [Aware From] '  + CHAR(13);
        SET @SQL=@SQL+'from vwSearchData WHERE ' + CHAR(13);

        SELECT @Main_minID = MIN(ID), @Main_maxID= MAX(ID)
        FROM SearchColumns
        SET @SQL=@SQL+'('
        WHILE @Main_minID <= @Main_maxID
        BEGIN
            SELECT @Main_Col = FieldName FROM SearchColumns WHERE ID = @Main_minID
            BEGIN

                SELECT @Sub_minID = MIN(ID), @Sub_maxID= MAX(ID) FROM #SearchFilter
                WHILE @Sub_minID <= @Sub_maxID
                BEGIN
                    SELECT @Sub_Col = FilterName FROM #SearchFilter WHERE ID = @Sub_minID
                    SET @SQL=@SQL+'(' + @Main_Col + ' LIKE  ''%'+@Sub_Col+'%'') OR '
                    SET @Sub_minID = @Sub_minID + 1
                END
            END
            SET @Main_minID = @Main_minID + 1
        END
        SET @SQL=SUBSTRING(@SQL, 1, LEN(@SQL)-4) + CHAR(13);
        SET @SQL=@SQL+')'

        IF OBJECT_ID('tempdb..#SearchFilter') IS NOT NULL
        BEGIN
            DROP TABLE #SearchFilter
        END
        EXEC(@SQL)

    END

C# code
---------
Dictionary<string,string> dParams=new Dictionary<string,string>();
            if (txtSearch.Text.Trim() == "")
                return;
            dParams.Add("@FilterXML",Utility.BuilXML(txtSearch.Text.Trim()));
            DataSet ds = DataRetrival.ExecuteSP("SearchCVData", dParams);

            if (ds != null)
            {
                if (ds.Tables.Count > 0)
                {
                    dgList.Invoke((Action)(() => dgList.DataSource = ds.Tables[0]));
                    SetWidth();
                }
            }

public static string BuilXML(string strSearch)
        {
             string strXML="";
            if (strSearch.Trim() != "")
            {
                string[] data = strSearch.Trim().Split(',');
                XElement xml = new XElement("Filter");
                for (int count = 0; count <= data.Length-1; count++)
                {
                    XElement elm = new XElement("value", data[count]);
                    xml.Add(elm);
                }
                strXML = xml.ToString().Replace("\r\n", string.Empty);
            }
            return strXML;
        }

        public static Form CenterForm(this Form child, Form parent)
        {
            child.StartPosition = FormStartPosition.Manual;
            child.Location = new Point(child.MdiParent.ClientSize.Width / 2 - child.Width / 2, child.MdiParent.ClientSize.Height / 2 - child.Height / 2);
            return child;
        }


public static DataSet ExecuteSP(string sprocName, Dictionary<string, string> paramList)
        {
                SqlCommand cmd = new SqlCommand();
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = sprocName;
                cmd.Connection = DataLayer.DataConnection.cnnLocal;

                //loop through the dictionary
                foreach (string key in paramList.Keys)
                {
                    cmd.Parameters.AddWithValue(key, paramList[key]);
                }

                SqlDataAdapter da = new SqlDataAdapter(cmd);
                DataSet ds = new DataSet();
                da.Fill(ds);

                //release the resource
                cmd = null;
                da = null;

                return ds;

        }

此示例sql用于搜索多列

SELECT * FROM ADDRESS WHERE
((NAME LIKE 'Bill%') OR (CITY LIKE 'Bill%') OR (COMPANY LIKE 'Bill%'))
AND
((NAME LIKE 'Seattle%') OR (CITY LIKE 'Seattle%') OR (COMPANY LIKE 'Seattle%'))

0 个答案:

没有答案