文字列 の lastindex を取得することを含む文字列から値を解析しようとしています。現在、私はひもを逆にすることを含む恐ろしいハックをしています:
SELECT REVERSE(SUBSTRING(REVERSE(DB_NAME()), 1,
CHARINDEX('_', REVERSE(DB_NAME()), 1) - 1))
私にとって、このコードはほとんど読めません。 SQL Server 2016にアップグレードしたばかりですが、もっと良い方法があるといいのですが。ある?
最後の_
の後のすべてが必要な場合は、次を使用します。
select right(db_name(), charindex('_', reverse(db_name()) + '_') - 1)
以前にすべてが必要な場合は、left()
を使用します。
select left(db_name(), len(db_name()) - charindex('_', reverse(db_name()) + '_'))
選択した文字に対してLastIndexOfを返す2つの関数、1を書きました。
CREATE FUNCTION dbo.LastIndexOf(@source nvarchar(80), @pattern char)
RETURNS int
BEGIN
RETURN (LEN(@source)) - CHARINDEX(@pattern, REVERSE(@source))
END;
GO
1。このLastIndexOfの前の文字列を返します。たぶんそれは誰かに役立つでしょう。
CREATE FUNCTION dbo.StringBeforeLastIndex(@source nvarchar(80), @pattern char)
RETURNS nvarchar(80)
BEGIN
DECLARE @lastIndex int
SET @lastIndex = (LEN(@source)) - CHARINDEX(@pattern, REVERSE(@source))
RETURN SUBSTRING(@source, 0, @lastindex + 1)
-- +1 because index starts at 0, but length at 1, so to get up to 11th index, we need LENGTH 11+1=12
END;
GO
CREATE FUNCTION dbo.LastIndexOf(@text NTEXT, @delimiter NTEXT)
RETURNS INT
AS
BEGIN
IF (@text IS NULL) RETURN NULL;
IF (@delimiter IS NULL) RETURN NULL;
DECLARE @Text2 AS NVARCHAR(MAX) = @text;
DECLARE @Delimiter2 AS NVARCHAR(MAX) = @delimiter;
DECLARE @Index AS INT = CHARINDEX(REVERSE(@Delimiter2), REVERSE(@Text2));
IF (@Index < 1) RETURN 0;
DECLARE @ContentLength AS INT = (LEN('|' + @Text2 + '|') - 2);
DECLARE @DelimiterLength AS INT = (LEN('|' + @Delimiter2 + '|') - 2);
DECLARE @Result AS INT = (@ContentLength - @Index - @DelimiterLength + 2);
RETURN @Result;
END
ここから分割された文字列 のいずれかを取得したら、このようなセットベースの方法でそれを行うことができます。
declare @string varchar(max)
set @string='C:\Program Files\Microsoft SQL Server\MSSQL\DATA\AdventureWorks_Data.mdf'
;with cte
as
(select *,row_number() over (order by (select null)) as rownum
from [dbo].[SplitStrings_Numbers](@string,'\')
)
select top 1 item from cte order by rownum desc
**Output:**
AdventureWorks_Data.mdf
いいえ、SQLサーバーにはLastIndexOfがありません。
これは利用可能な文字列です関数
ただし、いつでも独自の関数を作成できます
CREATE FUNCTION dbo.LastIndexOf(@source text, @pattern char)
RETURNS
AS
BEGIN
DECLARE @ret text;
SELECT into @ret
REVERSE(SUBSTRING(REVERSE(@source), 1,
CHARINDEX(@pattern, REVERSE(@source), 1) - 1))
RETURN @ret;
END;
GO
まったく同じ要件を持っているが、REVERSE
関数を持たない異なる種類のデータベースのための、同様の問題の解決策を探しているときに、このスレッドに出会いました。
私の場合、これはOpenEdge(Progress)データベースの場合で、構文が少し異なります。これにより、INSTR
関数が利用可能になりました ほとんどのOracle型付きデータベースが提供 。
そこで、次のコードを思い付きました。
SELECT
INSTR(foo.filepath, '/',1, LENGTH(foo.filepath) - LENGTH( REPLACE( foo.filepath, '/', ''))) AS IndexOfLastSlash
FROM foo
ただし、OpenEdge(Progress)データベースである特定の状況では、文字を空の文字に置き換えると元の文字と同じ長さになるため、これは望ましい動作になりませんでした文字列。これはあまり意味がありませんが、以下のコードで問題を回避できました。
SELECT
INSTR(foo.filepath, '/',1, LENGTH( REPLACE( foo.filepath, '/', 'XX')) - LENGTH(foo.filepath)) AS IndexOfLastSlash
FROM foo
今、私はこのコードがT-SQLの問題を解決しないことを理解しています。なぜなら、を提供するINSTR
関数に代わるものがないからですOccurence
プロパティ。
念のため、このスカラー関数を作成するために必要なコードを追加して、上記の例で使用したのと同じ方法で使用できるようにします。そして、OPが望んだことを正確に行い、SQL ServerのLastIndexOfメソッドとして機能します。
-- Drop the function if it already exists
IF OBJECT_ID('INSTR', 'FN') IS NOT NULL
DROP FUNCTION INSTR
GO
-- User-defined function to implement Oracle INSTR in SQL Server
CREATE FUNCTION INSTR (@str VARCHAR(8000), @substr VARCHAR(255), @start INT, @occurrence INT)
RETURNS INT
AS
BEGIN
DECLARE @found INT = @occurrence,
@pos INT = @start;
WHILE 1=1
BEGIN
-- Find the next occurrence
SET @pos = CHARINDEX(@substr, @str, @pos);
-- Nothing found
IF @pos IS NULL OR @pos = 0
RETURN @pos;
-- The required occurrence found
IF @found = 1
BREAK;
-- Prepare to find another one occurrence
SET @found = @found - 1;
SET @pos = @pos + 1;
END
RETURN @pos;
END
GO
明らかなことを避けるために、REVERSE
関数が使用可能な場合、このスカラー関数を作成する必要はなく、次のように必要な結果を得ることができます。
SELECT
LEN(foo.filepath) - CHARINDEX('\', REVERSE(foo.filepath))+1 AS LastIndexOfSlash
FROM foo