CREATE 
  FUNCTION [dbo].[LEWI_SPLT_STR](@String NVARCHAR(4000), @SplitChar NVARCHAR(10))
  RETURNS @table TABLE (COL VARCHAR (100)) AS  
BEGIN  
   DECLARE  @Index  INT  
   SET  @Index  =  0  
        IF @String <> ''
        BEGIN            
            IF RIGHT(@String,1)<> @SplitChar 
            SET @String = @String + @SplitChar
            IF LEFT(@String,1) = @SplitChar 
            SET @String = STUFF(@String, 1, 1, '')
        End
       WHILE  CHARINDEX(@SplitChar,@String,@Index)  >  0    
       BEGIN  
           INSERT INTO @table(COL) 
           VALUES (SUBSTRING(@String, @Index, CHARINDEX(@SplitChar, @String,@Index) - @Index))
           SET @index = CHARINDEX(@SplitChar, @String, @Index) + 1 
       END  
RETURN  
END|唐山|山曹|曹妃|妃甸|甸吸|吸引|引国|国内|内外|外目|目光|
|
不能正常工作提示
第 1 行: '|' 附近有语法错误。
字符串 ')
' 之前有未闭合的引号|唐山|曹|妃|甸|吸|引|国|内|外|目|光|
|
可以正常工作.何故????

解决方案 »

  1.   

    是分解:¦唐山 ¦山曹 ¦曹妃 ¦妃甸 ¦甸吸 ¦吸引 ¦引国 ¦国内 ¦内外 ¦外目 ¦目光 ¦ ?
    /*
    标题:分解字符串并查询相关数据
    作者:爱新觉罗.毓华 
    时间:2008-03-18
    地点:广东深圳
    说明:通过使用函数等方法分解字符串查询相关数据。问题:通过分解一个带某种符号分隔的字符串在数据库中查找相关数据。
    例如 @str = '1,2,3',查询下表得到记录1,4,5,6
    ID TypeID
    1  1,2,3,4,5,6,7,8,9,10,11,12
    2  2,3 
    3  3,7,8,9 
    4  2,6 
    5  4,5
    6  6,7 
    */
    -----------------------------
    create table tb (ID int , TypeID varchar(30)) 
    insert into tb values(1 , '1,2,3,4,5,6,7,8,9,10,11,12') 
    insert into tb values(2 , '2,3') 
    insert into tb values(3 , '3,7,8,9') 
    insert into tb values(4 , '2,6') 
    insert into tb values(5 , '4,5')
    insert into tb values(6 , '6,7')
    go
    -----------------------------
    --如果仅仅是一个,如@str = '1'.
    declare @str as varchar(30)
    set @str = '1'
    select * from tb where charindex(',' + @str + ',' , ',' + TypeID + ',') > 0
    select * from tb where ',' + TypeID + ',' like '%,' + @str + ',%'
    /*
    ID          TypeID                         
    ----------- ------------------------------ 
    1           1,2,3,4,5,6,7,8,9,10,11,12
    (所影响的行数为 1 行)
    */-----------------------------
    --如果包含两个,如@str = '1,2'.
    declare @str as varchar(30)
    set @str = '1,2'
    select * from tb where charindex(',' + left(@str , charindex(',' , @str) - 1) + ',' , ',' + typeid + ',') > 0 or 
      charindex(',' + substring(@str , charindex(',' , @str) + 1 , len(@str)) + ',' , ',' + typeid + ',') > 0
    select * from tb where ',' + typeid + ',' like '%,' + left(@str , charindex(',' , @str) - 1) + ',%' or 
      ',' + typeid + ',' like '%,' + substring(@str , charindex(',' , @str) + 1 , len(@str)) + ',%'
    /*
    ID          TypeID                         
    ----------- ------------------------------ 
    1           1,2,3,4,5,6,7,8,9,10,11,12
    2           2,3
    4           2,6
    (所影响的行数为 3 行)
    */-------------------------------------------
    --如果包含三个或四个,用PARSENAME函数来处理.
    declare @str as varchar(30)
    set @str = '1,2,3,4'
    select * from tb where 
      charindex(',' + parsename(replace(@str , ',' , '.') , 4) + ',' , ',' + typeid + ',') > 0 or
      charindex(',' + parsename(replace(@str , ',' , '.') , 3) + ',' , ',' + typeid + ',') > 0 or
      charindex(',' + parsename(replace(@str , ',' , '.') , 2) + ',' , ',' + typeid + ',') > 0 or
      charindex(',' + parsename(replace(@str , ',' , '.') , 1) + ',' , ',' + typeid + ',') > 0 
    select * from tb where 
      ',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 4) + ',%' or
      ',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 3) + ',%' or
      ',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 2) + ',%' or
      ',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 1) + ',%'
    /*
    ID          TypeID                         
    ----------- ------------------------------ 
    1           1,2,3,4,5,6,7,8,9,10,11,12
    2           2,3
    3           3,7,8,9
    4           2,6
    5           4,5
    (所影响的行数为 5 行)
    */---------------------------------------
    --如果超过四个,则只能使用函数或动态SQL来分解并查询数据。
    /*
    名称:fn_split函数.
    功能:实现字符串分隔功能的函数
    */
    create function dbo.fn_split(@inputstr varchar(8000), @seprator varchar(10))
    returns @temp table (a varchar(200))
    as 
    begin
      declare @i int
      set @inputstr = rtrim(ltrim(@inputstr))
      set @i = charindex(@seprator , @inputstr)
      while @i >= 1
      begin
        insert @temp values(left(@inputstr , @i - 1))
        set @inputstr = substring(@inputstr , @i + 1 , len(@inputstr) - @i)
        set @i = charindex(@seprator , @inputstr)
      end
      if @inputstr <> '\'
      insert @temp values(@inputstr)
      return 
    end
    go--调用
    declare @str as varchar(30)
    set @str = '1,2,3,4,5'select distinct m.* from tb m,
    (select * from dbo.fn_split(@str,',')) n
    where charindex(',' + n.a + ',' , ',' + m.typeid + ',') > 0drop table tb
    drop function dbo.fn_split /*
    ID          TypeID                         
    ----------- ------------------------------ 
    1           1,2,3,4,5,6,7,8,9,10,11,12
    2           2,3
    3           3,7,8,9
    4           2,6
    5           4,5
    (所影响的行数为 5 行)
    */------------------------------------------
    --使用动态SQL的语句。
    declare @str varchar(200)
    declare @sql as varchar(1000)
    set @str = '1,2,3,4,5'
    set @sql = 'select ''' + replace(@str , ',' , ''' as id union all select ''')
    set @sql = @sql + ''''
    set @sql = 'select distinct a.* from tb a , (' + @sql + ') b where charindex(' + ''','' + b.id + ' + ''',''' + ' , ' + ''','' + a.typeid + ' + ''',''' + ') > 0 '
    exec (@sql)
    /*
    ID          TypeID                         
    ----------- ------------------------------ 
    1           1,2,3,4,5,6,7,8,9,10,11,12
    2           2,3
    3           3,7,8,9
    4           2,6
    5           4,5
    (所影响的行数为 5 行)
    */
      

  2.   

    /*
    功能:实现split功能的函数
    */create function dbo.fn_split 
    (
    @inputstr varchar(8000), 
    @seprator varchar(10)
    )
    returns @temp table (a varchar(200))
    as begin
    declare @i intset @inputstr = rtrim(ltrim(@inputstr))
    set @i = charindex(@seprator, @inputstr)while @i >= 1
    begin
    insert @temp values(left(@inputstr, @i - 1))set @inputstr = substring(@inputstr, @i + 1, len(@inputstr) - @i)
    set @i = charindex(@seprator, @inputstr)
    endif @inputstr <> '\'
    insert @temp values(@inputstr)return 
    end
    go--调用declare @s varchar(1000)set @s='¦唐山 ¦山曹 ¦曹妃 ¦妃甸 ¦甸吸 ¦吸引 ¦引国 ¦国内 ¦内外 ¦外目 ¦目光 ¦ 'select * from dbo.fn_split(@s,'¦')drop function dbo.fn_split 
    /*
    a       
    --------唐山 
    山曹 
    曹妃 
    妃甸 
    甸吸 
    吸引 
    引国 
    国内 
    内外 
    外目 
    目光 
    (所影响的行数为 13 行)
    */
      

  3.   

    @dawugui 
    您的函数所带来的效果仍然是第 1 行: '|' 附近有语法错误。
    字符串 ')
    ' 之前有未闭合的引号。我用给的SQL 2000 难道这个版本有问题?
      

  4.   

    我的函数,你的字符串,结果都在上面了,是通过sql server 2000得出的结果.
    经过测试没有问题.
      

  5.   

    恩,我也觉得奇怪....不知何故.
    因为我直接用IDE模式调用的函数(EMS)declare @inputstr varchar(1000)set @inputstr='|唐山|山曹|曹妃|妃甸|甸吸|吸引|引国|国内|内外|外目|目光|'SELECT * FROM dbo.fn_split ( @inputstr, '|');这样调用却又不会出现问题.而且这样调用的时候,我一开始帖的那个函数也不会出现问题...
    奇怪了,很奇怪,
      

  6.   


    CREATE PROCEDURE [dbo].[LEWI_RLTD_KIWD_LNKR]
    @ShowNum VARCHAR(50),
    @TableName VARCHAR(50),
    @Condition VARCHAR(50),
    @Sorting VARCHAR(50),
    @ContentID VARCHAR(50)
    AS
    BEGIN
    EXEC
    ('
        DECLARE @GetKeyword NVARCHAR(50)
        DECLARE @String NVARCHAR(4000)
        SELECT @String=Keyword FROM '+@TableName+' WHERE id='''+@ContentID+''' AND Keyword != ''||''
        SELECT TOP 1 @Getkeyword=COL FROM dbo.LEWI_SPLT_STR(@String,''|'')
        SELECT @String=cast(arrGeneralID AS VARCHAR(4000)) FROM PE_Keywords WHERE Keywordtext=@GetKeyword
        SELECT TOP '+@ShowNum+'  C.Title,C.GeneralID,C.UpdateTime,C.Hits FROM dbo.PE_CommonModel C INNER JOIN dbo.LEWI_SPLT_STR(@String,'','') D ON C.GeneralID =D.COL WHERE C.GeneralID!='''+@ContentID+''' '+ @Condition +'ORDER BY '+ @Sorting
    )
    END为存储过程,这部分出错的
    将 nvarchar 值 '|唐山|山曹|曹妃|妃甸|甸吸|吸引|引国|国内|内外|外目|目光|' 转换为数据类型为 int 的列时发生语法错误。

    但不知怎么修改.
      

  7.   

    也可以这样
    create  PROCEDURE pr_SepStr  @Asqlstring VARCHAR(8000), --输入的SQL语句
                                    @sep VARCHAR(10),  --输入分隔符
                                    @SQL_OUT VARCHAR(8000) output --返回用分隔符分开的结果集
    /*
    request=
            只能返回一个结果集的SQL语句
            传入SQL语句的第一条语句必须是SELECT语句,其后可以跟随非SELECT语句(但无多大作用)
    function=
            将其结果集中的每一条记录用@sep中存储的字符分隔开,并通过@SQL_OUT输出。
    */
    AS
    --建临时表
    IF OBJECT_ID('TEMPDB..#SepString1') IS NULL
            CREATE TABLE #SepString1 (SqlOut varchar(8000))
    --插入初始值
    INSERT #SepString1 (SqlOut) SELECT ''
    SET @SQL_OUT = 
    '
    DECLARE @ALine VARCHAR(8000)
    DECLARE tnames_cursor CURSOR LOCAL FAST_FORWARD FOR '+CHAR(13)+CHAR(10)+ @asqlstring +CHAR(13)+CHAR(10)+
    '
    OPEN tnames_cursor
    FETCH NEXT FROM tnames_cursor INTO @ALine
    WHILE ( @@FETCH_STATUS = 0)
    BEGIN 
            --将结果集用分隔符分开 
            UPDATE #SepString1 
            SET SqlOut = SqlOut + CASE WHEN @ALine <> '''' AND SqlOut <> '''' THEN '''+@sep+''' ELSE '''' END + ISNULL(@ALine,'''')
            FETCH NEXT FROM tnames_cursor INTO @ALine
    END 
    CLOSE tnames_cursor
    DEALLOCATE tnames_cursor
    '
    EXEC (@SQL_OUT)
    SELECT @SQL_OUT = SqlOut FROM #SepString1
      

  8.   


    CREATE PROCEDURE [dbo].[LEWI_RLTD_KIWD_LNKR]
    @ShowNum VARCHAR(50),
    @TableName VARCHAR(50),
    @Condition VARCHAR(50),
    @Sorting VARCHAR(50),
    @ContentID VARCHAR(50)
    AS
    BEGIN
    EXEC
    ('
        DECLARE @GetKeyword NVARCHAR(50)
        DECLARE @String NVARCHAR(4000)
        SELECT @String=Keyword FROM '+@TableName+' WHERE id='''+@ContentID+''' AND Keyword != ''||''
        PRINT @String
        SELECT TOP 1 @GetKeyword=COL FROM dbo.LEWI_SPLT_STR(@String,''|'')
        PRINT @Getkeyword
        SELECT @String = cast(arrGeneralID AS VARCHAR(4000)) FROM PE_Keywords WHERE Keywordtext=@GetKeyword
        PRINT @String
        SELECT TOP '+@ShowNum+'  C.Title,C.GeneralID,C.UpdateTime,C.Hits FROM dbo.PE_CommonModel C INNER JOIN dbo.LEWI_SPLT_STR(@String,'','') D ON C.GeneralID =D.COL WHERE C.GeneralID!='''+@ContentID+''' '+ @Condition +'ORDER BY '+ @Sorting
    )
    END问题已经查出来...主要是因为
    得到的TOP 1 @GetKeyword 的值在 并不在 PE_Keywords表中比如,@GetKeyword的值 为 手机
    而pe_keywords表中 的Keywordtext表中并无 手机这个关键字,所以无法转换 类型文ntext的arrGeneralID但是我仍然不知道如何判断 当 KeyworkdText中没有 @GetKeyword值的时候 不返回数据.