次の文字列値があるとします。
declare @cs nvarchar(100) =
'Data Source=server\instance;Initial Catalog=MyDatabase;Integrated Security=True';
MyDatabase
文字列を抽出するT-SQLとは何@cs
ですか?
または、自分で理解するための手段として、どのT-SQL関数を調べる必要がありますか?
次の文字列値があるとします。
declare @cs nvarchar(100) =
'Data Source=server\instance;Initial Catalog=MyDatabase;Integrated Security=True';
MyDatabase
文字列を抽出するT-SQLとは何@cs
ですか?
または、自分で理解するための手段として、どのT-SQL関数を調べる必要がありますか?
きれいではなく、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
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