2015-06-11 147 views
0

我有一個接收字符串作爲參數的Sql過程。 現在我需要執行的任務是,參數包含由兩種不同的分隔符分隔的數據,即「:」「」在Sql中使用分隔符分隔的數據過程

有兩列在DB 標識

 sample Data: "10:0,11:1,12:3,13:4,15:5,16:6" 
    In This case   Ids are: 10,11,12,13,14,15,16 
    and their respective values are: 1,2,3,4,5,6 

現在我想在數據庫中插入這些值。 你能提出一個解決方案嗎?

+0

您使用的是MySQL還是MS SQL Server? (兩種不同的產品,使用不同的存儲過程。) – jarlh

+0

根據您的sql客戶端(意味着執行存儲過程的代碼),您可能可以使用表值參數。這將是最好的解決方案。 –

+0

@jarlh我猜測sql服務器,因爲OP添加了sql-server和sql-server-2008標籤 –

回答

0

您可以使用下面的功能:

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 = ',' 

     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)[email protected]) 
      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 

CREATE TABLE #Test 
(
    Item NVARCHAR(1000) 
) 

INSERT INTO #Test 
SELECT * FROM Split('10:0,11:1,12:3,13:4,15:5,16:6', ':') 

SELECT f.* FROM #Test t 
CROSS APPLY Split(t.Item, ',') f 

DROP TABLE #Test 
+0

由於字符串分配器走這個「啃」風格是最差的表演者。它返回正確的結果比許多其他方法慢得多。 http://sqlperformance.com/2012/07/t-sql-queries/split-strings –

1

您可以使用下面的函數,它會處理你的兩個分隔符spli

CREATE FUNCTION dbo.MultipleSplitStrings 
(
    @List  NVARCHAR(MAX), 
    @Separator1 Varchar(100), 
    @Separator2 Varchar(100) 
) 
RETURNS TABLE 
AS 

    RETURN 
    ( 
     SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)') 
     FROM 
     ( 
     SELECT x = CONVERT(XML, '<i>' 
      + REPLACE(REPLACE(@List, ISNULL(@Separator1,''), '</i><i>') , ISNULL(@Separator2,''), '</i><i>') 
      + '</i>').query('.') 
    ) AS a CROSS APPLY x.nodes('i') AS y(i) 
    ); 

GO 

Select * From dbo.MultipleSplitStrings ('10:0,11:1,12:3,13:4,15:5,16:6',',',':') 

結果:

item 
10 
0 
11 
1 
12 
3 
13 
4 
15 
5 
16 
6 
2
IF OBJECT_ID('tempdb..#Test') IS NOT NULL 
DROP TABLE #Test 
GO 

CREATE TABLE #Test(ID INT,Val INT) 

DECLARE @t table (val varchar(50)) 
INSERT INTO @t (val)values ('10:0,11:1,12:3,13:4,15:5,16:6') 


;WITH CTE AS (
SELECT 
    Split.a.value('.', 'VARCHAR(100)') AS String 
FROM (SELECT 
     CAST ('<M>' + REPLACE([val], ',', '</M><M>') + '</M>' AS XML) AS String 
    FROM @t) AS A CROSS APPLY String.nodes ('/M') AS Split(a)) 
    INSERT INTO #Test 
    select SUBSTRING(String,0,CHARINDEX(':',String)),REVERSE(SUBSTRING(reverse(String),0,CHARINDEX(':',reverse(String)))) from cte 

    select * from #test 
+0

您可以使用'RIGHT'替換'REVERSE(SUBSTRING(REVERSE(String),0, CHARINDEX(':',REVERSE(String))))' (@s,LEN(@s) - CHARINDEX(':',@s))' –

+0

嗨..感謝您的快速響應..這個查詢工作在一定程度上,但我需要添加一個where子句插入查詢..其中,如果我有一個鍵值對說'10:1,11:2',我也需要查找值'10',並插入值爲1的resopective列。 Right現在插入了一個額外的空行,我無法弄清楚爲什麼會發生這種情況。 我有什麼意義嗎? –

+0

@GiorgiNakeuri你可以請建議如何在上面的查詢中添加where子句? –