0

次の文字列値があるとします。

declare @cs nvarchar(100) = 
   'Data Source=server\instance;Initial Catalog=MyDatabase;Integrated Security=True';

MyDatabase文字列を抽出するT-SQLとは何@csですか?

または、自分で理解するための手段として、どのT-SQL関数を調べる必要がありますか?

4

2 に答える 2

0

きれいではなく、regex / clr patindex&substringsを使用してこれをより速く行うことができると確信していますが、非常に迅速で簡単な方法は、以下の分割関数を使用して次のようなことを行うことです。

使用例:

DECLARE @cs NVARCHAR(100) = 'Data Source=server\instance;Initial Catalog=MyDatabase;Integrated Security=True';

SELECT  id ,
        Data ,
        dbo.fnParseString(2, '=', Data)
FROM    dbo.fnc_Split(@cs, ';')
WHERE   Data LIKE '%Initial Catalog%'

戻り値:

2        Initial Catalog=MyDatabase        MyDatabase

分割関数に関しては、最初の関数は文字列をテーブルに分割し、2番目の関数は文字列を列に分割します。

テーブルに分割:

CREATE FUNCTION dbo.fnc_Split
    (
      @Data VARCHAR(2000) ,
      @Sep VARCHAR(5)
    )
RETURNS @Temp TABLE
    (
      Id INT IDENTITY(1, 1) ,
      Data NVARCHAR(100)
    )
AS 
    BEGIN
        DECLARE @Cnt INT
        SET @Cnt = 1
        WHILE ( CHARINDEX(@Sep, @Data) > 0 ) 
            BEGIN
                INSERT  INTO @Temp
                        ( data
                        )
                        SELECT  Data = LTRIM(RTRIM(SUBSTRING(@Data, 1, CHARINDEX(@Sep, @Data) - 1)))
                SET @Data = SUBSTRING(@Data, CHARINDEX(@Sep, @Data) + 1, LEN(@Data))
                SET @Cnt = @Cnt + 1
            END
        INSERT  INTO @Temp
                ( data )
                SELECT  Data = LTRIM(RTRIM(@Data))
        RETURN
    END
GO

列に分割:

CREATE FUNCTION dbo.fnParseString
    (
      @Section SMALLINT ,
      @Delimiter CHAR ,
      @Text VARCHAR(MAX)
    )
RETURNS VARCHAR(8000)
AS 
    BEGIN
        DECLARE @NextPos SMALLINT ,
            @LastPos SMALLINT ,
            @Found SMALLINT

        --#### Uncomment the following 2 lines to emulate PARSENAME functionality
        --IF @Section > 0 
        --    SELECT  @Text = REVERSE(@Text)

        SELECT  @NextPos = CHARINDEX(@Delimiter, @Text, 1) ,
                @LastPos = 0 ,
                @Found = 1

        WHILE @NextPos > 0
            AND ABS(@Section) <> @Found 
            SELECT  @LastPos = @NextPos ,
                    @NextPos = CHARINDEX(@Delimiter, @Text, @NextPos + 1) ,
                    @Found = @Found + 1

        RETURN  CASE
            WHEN @Found <> ABS(@Section) OR @Section = 0 THEN NULL
            --#### Uncomment the following lines to emulate PARSENAME functionality
            --WHEN @Section > 0 THEN REVERSE(SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END))
            WHEN @Section > 0 THEN SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END)

            ELSE SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END)
        END
    END
于 2012-06-29T09:20:02.950 に答える
0

from_tableをテーブルに変更し、接続文字列フィールドをフィールドに変更するだけで、これがはるかに簡単になる場合があります。

SELECT SUBSTRING(SUBSTRING([ConnectionString], CHARINDEX('Initial Catalog=', [ConnectionString]) + LEN('Initial Catalog='), 100), 0, CHARINDEX(';', SUBSTRING([ConnectionString], CHARINDEX('Initial Catalog=', [ConnectionString]) + LEN('Initial Catalog='), 100)))
AS DbName
FROM [from_table]

文字列を取得した後、次のようなことをしたいと思うかもしれません:(
名前を繰り返していくつかのデータベースをクエリする)

DECLARE @DbName varchar(max)
DECLARE @QaQuery NVARCHAR(MAX);

DECLARE MY_CURSOR CURSOR 
  LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR 
SELECT SUBSTRING(SUBSTRING([ConnectionString], CHARINDEX('Initial Catalog=', [ConnectionString]) + LEN('Initial Catalog='), 100), 0, CHARINDEX(';', SUBSTRING([ConnectionString], CHARINDEX('Initial Catalog=', [ConnectionString]) + LEN('Initial Catalog='), 100)))
AS Connections
FROM [ConnTable]

OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO @DbName
WHILE @@FETCH_STATUS = 0
BEGIN 
    --PRINT @DbName
    SET @QaQuery = N'SELECT TOP 10 [RecordID],[SomeStuff]
                        FROM ['+@DbName+'].[dbo].[SomeTable]
                        WHERE [SomeStuff] IS NOT NULL'
  EXEC sp_executesql @QaQuery;
  FETCH NEXT FROM MY_CURSOR INTO @DbName
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
于 2015-01-05T12:17:17.923 に答える