我需要创建这个表函数。该函数需要从传递的参数返回单个单词,如:hello,hhuu,value
表函数应返回:
hello,
hhuu,
value
但我总是遇到一些错误,请你能帮助我吗?
答案 0 :(得分:0)
请看一下这篇文章: http://www.codeproject.com/Tips/625872/Convert-a-CSV-delimited-string-to-table-column-in
你可以使用''(空格)作为分隔符。
SELECT * FROM dbo.CSVtoTable('hello, hhuu, value', ' ')
答案 1 :(得分:0)
DECLARE @input_char VARCHAR(255)
SET @input_char = 'hello, hhuu, value'
;WITH cte AS (
SELECT
CAST('<r>' + REPLACE(@input_char, ' ', '</r><r>') + '</r>' AS XML) AS input_char
)
SELECT
rtrim( LTRIM (xTable.xColumn.value('.', 'VARCHAR(MAX)')) ) AS input_char
FROM cte
CROSS APPLY input_char.nodes('//r') AS xTable(xColumn)
答案 2 :(得分:0)
我多次使用以下功能。这有点长,原谅我,但它已成为我的一个很好的工具。
CREATE Function [dbo].[ParseText2Table]
(
@p_SourceText varchar(MAX)
,@p_Delimeter varchar(100) = ',' --default to comma delimited.
)
RETURNS @retTable TABLE
(
POSITION INT
,Int_Value bigint
,Num_value REAL--Numeric(18,3)
,txt_value varchar(MAX)
)
AS
BEGIN
DECLARE @tmpTable TABLE
(
Position2 INT IDENTITY(1,1) PRIMARY KEY
,Int_Value bigint
,Num_value REAL--Numeric(18,3)
,txt_value varchar(MAX)
)
DECLARE @w_Continue INT
,@w_StartPos INT
,@w_Length INT
,@w_Delimeter_pos INT
,@w_tmp_int bigint
,@w_tmp_num REAL--numeric(18,3)
,@w_tmp_txt varchar(MAX)
,@w_Delimeter_Len INT
IF len(@p_SourceText) = 0
BEGIN
SET @w_Continue = 0 -- force early exit
END
ELSE
BEGIN
-- if delimiter is ' ' change
IF @p_Delimeter = ' '
BEGIN
SET @p_SourceText = replace(@p_SourceText,' ','ÿ')
SET @p_Delimeter = 'ÿ'
END
-- parse the original @p_SourceText array into a temp table
SET @w_Continue = 1
SET @w_StartPos = 1
SET @p_SourceText = RTRIM( LTRIM( @p_SourceText))
SET @w_Length = DATALENGTH( RTRIM( LTRIM( @p_SourceText)))
SET @w_Delimeter_Len = len(@p_Delimeter)
END
WHILE @w_Continue = 1
BEGIN
SET @w_Delimeter_pos = CHARINDEX( @p_Delimeter
,(SUBSTRING( @p_SourceText, @w_StartPos
,((@w_Length - @w_StartPos) + @w_Delimeter_Len)))
)
IF @w_Delimeter_pos > 0 -- delimeter(s) found, get the value
BEGIN
SET @w_tmp_txt = LTRIM(RTRIM( SUBSTRING( @p_SourceText, @w_StartPos
,(@w_Delimeter_pos - 1)) ))
IF dbo.isReallyNumeric(@w_tmp_txt) = 1 --and not @w_tmp_txt in('.', '-', '+', '^')
BEGIN
--set @w_tmp_int = cast( cast(@w_tmp_txt as real) as bigint)--numeric) as bigint)
SET @w_tmp_int = CASE WHEN (CAST(@w_tmp_txt AS REAL) BETWEEN -9223372036854775808 AND 9223372036854775808) THEN CAST( CAST(@w_tmp_txt AS REAL) AS bigint) ELSE NULL END
SET @w_tmp_num = CAST( @w_tmp_txt AS REAL)--numeric(18,3))
END
ELSE
BEGIN
SET @w_tmp_int = NULL
SET @w_tmp_num = NULL
END
SET @w_StartPos = @w_Delimeter_pos + @w_StartPos + (@w_Delimeter_Len- 1)
END
ELSE -- No more delimeters, get last value
BEGIN
SET @w_tmp_txt = LTRIM(RTRIM( SUBSTRING( @p_SourceText, @w_StartPos
,((@w_Length - @w_StartPos) + @w_Delimeter_Len)) ))
IF dbo.isReallyNumeric(@w_tmp_txt) = 1 --and not @w_tmp_txt in('.', '-', '+', '^')
BEGIN
--set @w_tmp_int = cast( cast(@w_tmp_txt as real) as bigint)--as numeric) as bigint)
SET @w_tmp_int = CASE WHEN (CAST(@w_tmp_txt AS REAL) BETWEEN -9223372036854775808 AND 9223372036854775808) THEN CAST( CAST(@w_tmp_txt AS REAL) AS bigint) ELSE NULL end
SET @w_tmp_num = CAST( @w_tmp_txt AS REAL)--numeric(18,3))
END
ELSE
BEGIN
SET @w_tmp_int = NULL
SET @w_tmp_num = NULL
END
SELECT @w_Continue = 0
END
INSERT INTO @tmpTable VALUES( @w_tmp_int, @w_tmp_num, @w_tmp_txt )
END
INSERT INTO @retTable SELECT Position2, Int_Value ,Num_value ,txt_value FROM @tmpTable
RETURN
END
以上是上述支持功能:
CREATE FUNCTION dbo.isReallyInteger
(
@num VARCHAR(64)
)
RETURNS BIT
BEGIN
IF LEFT(@num, 1) = '-'
SET @num = SUBSTRING(@num, 2, LEN(@num))
RETURN CASE
WHEN PATINDEX('%[^0-9-]%', @num) = 0
AND CHARINDEX('-', @num) <= 1
AND @num NOT IN ('.', '-', '+', '^')
AND LEN(@num)>0
AND @num NOT LIKE '%-%'
THEN
1
ELSE
0
END
END
CREATE FUNCTION dbo.isReallyNumeric
(
@num VARCHAR(64)
)
RETURNS BIT
BEGIN
IF LEFT(@num, 1) = '-'
SET @num = SUBSTRING(@num, 2, LEN(@num))
DECLARE @pos TINYINT
SET @pos = 1 + LEN(@num) - CHARINDEX('.', REVERSE(@num))
RETURN CASE
WHEN PATINDEX('%[^0-9.-]%', @num) = 0
AND @num NOT IN ('.', '-', '+', '^')
AND LEN(@num)>0
AND @num NOT LIKE '%-%'
AND
(
((@pos = LEN(@num)+1)
OR @pos = CHARINDEX('.', @num))
)
THEN
1
ELSE
0
END
END
用法示例:
--Single Character Delimiter
--select * from dbo.ParseText2Table('100|120|130.56|Yes|Cobalt|Blue','|')
--select txt_value from dbo.ParseText2Table('100 120 130.56 Yes Cobalt Blue',' ') where Position = 3
--select * from dbo.ParseText2Table('100,120,130.56,Yes,Cobalt,Blue,,',',')
/*
POSITION Int_Value Num_value txt_value
----------- ----------- -------------------- --------------
1 100 100.000 100
2 120 120.000 120
3 131 130.560 130.56
4 NULL NULL Yes
5 NULL NULL Cobalt Blue
*/