可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a string like this:
72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX
This is basically 5 values in each of 3 rows (from an ASP.NET grid). I need to split this string apart into 5 columns and 3 rows in a SQL Server table. Individual values are separated by commas and rows by colons.
I found a function to split a string into pieces and I can get the rows out of this string:
declare @testString varchar(100)
set @testString = '72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX'
select *
from dbo.SplitString(@testString, ':')
gives me:
72594206916,2,1/2/08,Tacoma,WA
72594221856,5,5/7/13,San Francisco,CA
72594221871,99,12/30/12,Dallas,TX
This gives me a result set with the three rows (the function outputs a table). Can I call this function again at the same time and insert its output into a table somehow?
回答1:
assuming your split returns column name item
insert <table> (colname)
select y.item
from dbo.SplitString(@testString, ':') x
cross apply
dbo.SplitString(x.item, ',') y
回答2:
Function Definition by Romil
Create this Function in your Sql Server
CREATE FUNCTION Split (
@InputString VARCHAR(8000),
@Delimiter VARCHAR(50)
)
RETURNS @Items TABLE (
Item VARCHAR(8000)
)
AS
BEGIN
IF @Delimiter = ' '
BEGIN
SET @Delimiter = ','
SET @InputString = REPLACE(@InputString, ' ', @Delimiter)
END
IF (@Delimiter IS NULL OR @Delimiter = '')
SET @Delimiter = ','
--INSERT INTO @Items VALUES (@Delimiter) -- Diagnostic
--INSERT INTO @Items VALUES (@InputString) -- Diagnostic
DECLARE @Item VARCHAR(8000)
DECLARE @ItemList VARCHAR(8000)
DECLARE @DelimIndex INT
SET @ItemList = @InputString
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
WHILE (@DelimIndex != 0)
BEGIN
SET @Item = SUBSTRING(@ItemList, 0, @DelimIndex)
INSERT INTO @Items VALUES (@Item)
-- Set @ItemList = @ItemList minus one less item
SET @ItemList = SUBSTRING(@ItemList, @DelimIndex+1, LEN(@ItemList)-@DelimIndex)
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
END -- End WHILE
IF @Item IS NOT NULL -- At least one delimiter was encountered in @InputString
BEGIN
SET @Item = @ItemList
INSERT INTO @Items VALUES (@Item)
END
-- No delimiters were encountered in @InputString, so just return @InputString
ELSE INSERT INTO @Items VALUES (@InputString)
RETURN
END -- End Function
GO
Pass Your Parameteres
Since it is a Table Function you will SELECT * FROM this_Function like you would do with a table
declare @testString varchar(100)
set @testString = '72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX'
SELECT * FROM Split(@testString, ',')
Result Set
Item
72594206916
2
1/2/08
Tacoma
WA:72594221856
5
5/7/13
San Francisco
CA:72594221871
99
12/30/12
Dallas
Your Existing Code
select *
from dbo.SplitString(@testString, ':')
The Second Parameter needs to be the deliminator, Since you are Passing :
as the second parameter it is breaking you string where ever it finds :
in you passed string which is obviously in 2 places and you get back 3 values/Strings in the result set
String1/Value1 String2/Value2 String3/Value3
set @testString = '72594206916,2,1/2/08,Tacoma,WA : 72594221856,5,5/7/13,San Francisco,CA : 72594221871,99,12/30/12,Dallas,TX'
回答3:
Something similar to what M.Ali gave above, but shorter:
Use [Database_Name]
Go;
CREATE FUNCTION Split
(
@RowData nvarchar(MAX),
@SplitOn nvarchar(MAX)
)
RETURNS @RtnValue table
(
Data nvarchar(MAX)
)
AS
BEGIN
Declare @Cnt int
Set @Cnt = 1
While (Charindex(@SplitOn,@RowData)>0)
Begin
Insert Into @RtnValue (data)
Select
Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1)))
Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData))
Set @Cnt = @Cnt + 1
End
Insert Into @RtnValue (data)
Select Data = ltrim(rtrim(@RowData))
Return
END
Then select from the function as in the above example:
USE [Database_Name]
GO
declare @testString varchar(100)
set @testString = '72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX'
SELECT * FROM Split(@testString, ',')
回答4:
Create this SQL function:
CREATE FUNCTION [dbo].[StringSplit](@input NVARCHAR(MAX), @delimiter CHAR(1)=',')
RETURNS @returnTable TABLE(item NVARCHAR(100)) AS
BEGIN
IF @input IS NULL RETURN;
DECLARE @currentStartIndex INT, @currentEndIndex INT,@length INT;
SET @length=LEN(@input);
SET @currentStartIndex=1;
SET @currentEndIndex=CHARINDEX(@delimiter,@input,@currentStartIndex);
WHILE (@currentEndIndex<>0)
BEGIN
INSERT INTO @returnTable VALUES (LTRIM(SUBSTRING(@input, @currentStartIndex, @currentEndIndex-@currentStartIndex)))
SET @currentStartIndex=@currentEndIndex+1;
SET @currentEndIndex=CHARINDEX(@delimiter,@input,@currentStartIndex);
END
IF (@currentStartIndex <= @length)
INSERT INTO @returnTable
VALUES (LTRIM(SUBSTRING(@input, @currentStartIndex, @length-@currentStartIndex+1)));
RETURN;
END;
Usage example:
DECLARE @testString VARCHAR(100)
SET @testString = '72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX'
SELECT *
FROM [dbo].[StringSplit](@testString, DEFAULT)
Result (table):
72594206916
2
1/2/08
Tacoma
WA:72594221856
5
5/7/13
San Francisco
CA:72594221871
99
12/30/12
Dallas
回答5:
declare @fqdn_list varchar(max) = 'test1.qa.local,test2.qa.local,test3.qa.local'
-- temp table
DECLARE @fqdn_tbl TABLE ( fqdn nvarchar(50) )
INSERT INTO @fqdn_tbl SELECT LTRIM(RTRIM(split.a.value('.', 'NVARCHAR(MAX)'))) AS fqdn FROM (
SELECT CAST ('<M>' + REPLACE(@fqdn_list, ',', '</M><M>') + '</M>' AS XML) AS data ) AS a CROSS APPLY data.nodes ('/M') AS split(a)
select * from @fqdn_tbl
回答6:
You forgot the last line. In your example, the 'TX' is not taken into account. You shuld check the remaining text avec While loop