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 行: '|' 附近有语法错误。
字符串 ')
' 之前有未闭合的引号|唐山|曹|妃|甸|吸|引|国|内|外|目|光|
|
可以正常工作.何故????
/*
标题:分解字符串并查询相关数据
作者:爱新觉罗.毓华
时间: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 行)
*/
功能:实现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 行)
*/
您的函数所带来的效果仍然是第 1 行: '|' 附近有语法错误。
字符串 ')
' 之前有未闭合的引号。我用给的SQL 2000 难道这个版本有问题?
经过测试没有问题.
因为我直接用IDE模式调用的函数(EMS)declare @inputstr varchar(1000)set @inputstr='|唐山|山曹|曹妃|妃甸|甸吸|吸引|引国|国内|内外|外目|目光|'SELECT * FROM dbo.fn_split ( @inputstr, '|');这样调用却又不会出现问题.而且这样调用的时候,我一开始帖的那个函数也不会出现问题...
奇怪了,很奇怪,
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 的列时发生语法错误。
但不知怎么修改.
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
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值的时候 不返回数据.