使用TSQL解析命令行选项

时间:2013-07-05 18:09:40

标签: sql-server string tsql

我有一个字符串,它是一个命令行选项。让我们说它是

  

/server:server1.mydomain.com / username:user1 / password:“我的密码”   / other:“aa / bb \”cc“

我需要使用TSQL解析它并得到以下结果:

+----------+----------------------+
| Key      | Value                |
+----------+----------------------+
| server   | server1.mydomain.com |
| username | user1                |
| password | my password          |
| other    | aa /bb "cc           |
+----------+----------------------+

我知道TSQL是一种数据库语言,并不擅长这种任务。但我只想到它的可能性。 TSQL没有内置的正则表达式支持,很难完成此任务。任何人都可以尝试一下吗?感谢。

DECLARE @options NVARCHAR(MAX);
SELECT @options = N'/server:server1.mydomain.com /username:user1 /password:"my password" /other:"aa /bb \"cc"';

IF OBJECT_ID('dbo.store', N'U') IS NOT NULL DROP TABLE dbo.store;
CREATE TABLE dbo.store
(
    key NVARCHAR(MAX),
    value NVARCHAR(MAX)
)

// This is the result I want
// +----------+----------------------+
// | Key      | Value                |
// +----------+----------------------+
// | server   | server1.mydomain.com |
// | username | user1                |
// | password | my password          |
// | other    | aa /bb "cc           |
// +----------+----------------------+

2 个答案:

答案 0 :(得分:2)

你可以做点什么

USE [DEI]
GO
/****** Object:  UserDefinedFunction [dbo].[fnSplit]    Script Date: 07/06/2013 00:00:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create FUNCTION [dbo].[fnSplit](
   @sInputList VARCHAR(8000) -- List of delimited items
   , @sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items
 ) RETURNS @List TABLE (item VARCHAR(8000))

BEGIN
DECLARE @sItem VARCHAR(8000)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
 BEGIN
  SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
  @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

IF LEN(@sItem) > 0
 INSERT INTO @List SELECT @sItem
END

IF LEN(@sInputList) > 0
INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END

然后尝试以下查询:

DECLARE @options NVARCHAR(MAX);
SELECT @options = N'/server:server1.mydomain.com /username:user1 /password:"my password" /other:"aa /bb   \"cc"';


DECLARE @temp NVARCHAR(MAX);

set @temp = (SELECT REPLACE(REPLACE(REPLACE(REPLACE(@options,'/SERVER:' , '&&&&') , '/username:' ,  '&&&&'),'/password:' , '&&&&') , '/other:' , '&&&&'))

SELECT 
case 
when row_number() over(order by getdate()) = 1 then 'server' 
when row_number() over(order by getdate()) = 2 then 'username' 
when row_number() over(order by getdate()) = 3 then 'password' 
when row_number() over(order by getdate()) = 4 then 'other' 
end, *
FROM fnsplit(@temp , '&&&&') as a

答案 1 :(得分:0)

试试这个

SQL Fiddle Demo

DECLARE @options NVARCHAR(MAX)  = '/server:server1.mydomain.com /username:user1 /password:"my password" /other:"aa /bb \"cc"' 
    ,@str NVARCHAR(MAX)

WHILE LEN(@options) > 0
 BEGIN
    IF LEN(@options) - LEN(REPLACE(@options,':','')) >= 2
        BEGIN
            SELECT @str =  REVERSE(LEFT(@options, CHARINDEX(':', @options,CHARINDEX(':', @options)+ 1 )))
            SELECT @str = REVERSE(SUBSTRING(@str,CHARINDEX(' ',@str) + 1, LEN(@str)))
        END
     ELSE 
        SET @str = @options

    INSERT INTO store ([key],[value])
    SELECT --@str AS str
        SUBSTRING(@str, 2, CHARINDEX(':', @str) - 2 ) as [key]
        ,RIGHT(@str, LEN(@str) - CHARINDEX(':',@str)) as [value]
    SET  @options = LTRIM(SUBSTRING(@options,LEN(@str) + 1, LEN(@options))  )
 END

SELECT * from store