5

T-SQL を使用して、文字列内の数値を逆にする最も簡単な方法を見つけようとしています。そのため、文字列のようなTest123Hellohave Test321Hello.

[Before]           [After]
Test123Hello       Test321Hello
Tt143 Hello        Tt341 Hello
12Hll              21Hll
Tt123H3451end      Tt321H1543end
4

6 に答える 6

2

検索に使用PATINDEXして、結果の文字列に部分的に追加します。

CREATE FUNCTION [dbo].[fn_ReverseDigits]
(
    @Value nvarchar(max)   
)
RETURNS NVARCHAR(max)
AS
BEGIN

    IF @Value IS NULL
        RETURN NULL

    DECLARE 
        @TextIndex int = PATINDEX('%[^0-9]%', @Value), 
        @NumIndex int = PATINDEX('%[0-9]%', @Value), 
        @ResultValue nvarchar(max)  = ''

    WHILE LEN(@ResultValue) < LEN(@Value)
    BEGIN

        -- Set the index to end of the string if the index is 0
        SELECT @TextIndex = CASE WHEN @TextIndex = 0 THEN LEN(@Value) + 1 ELSE LEN(@ResultValue) + @TextIndex END
        SELECT @NumIndex = CASE WHEN @NumIndex = 0 THEN LEN(@Value) + 1 ELSE LEN(@ResultValue) + @NumIndex END

        IF @NumIndex < @TextIndex
            SELECT @ResultValue = @ResultValue + REVERSE(SUBSTRING(@Value, @NumIndex, @TextIndex -@NumIndex))
        ELSE
            SELECT @ResultValue = @ResultValue + (SUBSTRING(@Value, @TextIndex, @NumIndex - @TextIndex))

        -- Update index variables
        SELECT
            @TextIndex = PATINDEX('%[^0-9]%', SUBSTRING(@Value, LEN(@ResultValue) + 1, LEN(@Value) - LEN(@ResultValue))), 
            @NumIndex = PATINDEX('%[0-9]%', SUBSTRING(@Value, LEN(@ResultValue) + 1, LEN(@Value) - LEN(@ResultValue)))

    END


    RETURN @ResultValue
END

SQL のテスト

declare @Values table (Value varchar(20))
INSERT @Values VALUES
('Test123Hello'),
('Tt143 Hello'),
('12Hll'), 
('Tt123H3451end'),
(''),
(NULL)

SELECT Value, dbo.fn_ReverseDigits(Value) ReversedValue FROM @Values

結果

Value                ReversedValue
-------------------- --------------------
Test123Hello         Test321Hello
Tt143 Hello          Tt341 Hello
12Hll                21Hll
Tt123H3451end        Tt321H1543end

NULL                 NULL
于 2015-06-03T02:30:48.183 に答える
1

この関数を使用すると、複数の数字の出現も処理されます

create FUNCTION [dbo].[GetReverseNumberFromString] (@String VARCHAR(2000))
RETURNS VARCHAR(1000)
AS
BEGIN
    DECLARE @Count INT
    DECLARE @IntNumbers VARCHAR(1000)
    declare @returnstring varchar(max)=@String;
    SET @Count = 0
    SET @IntNumbers = ''

    WHILE @Count <= LEN(@String)
    BEGIN

        IF SUBSTRING(@String, @Count, 1) >= '0'
            AND SUBSTRING(@String, @Count, 1) <= '9'
        BEGIN
            SET @IntNumbers = @IntNumbers + SUBSTRING(@String, @Count, 1)

        END


        IF (
                SUBSTRING(@String, @Count + 1, 1) < '0'
                OR SUBSTRING(@String, @Count + 1, 1) > '9'
                )
            AND SUBSTRING(@String, @Count, 1) >= '0'
            AND SUBSTRING(@String, @Count, 1) <= '9'
        BEGIN

            SET @IntNumbers = @IntNumbers + ','
        END

        SET @Count = @Count + 1
    END
declare @RevStrings table (itemz varchar(50))

INSERT INTO @RevStrings(itemz)
select items from dbo.Split(@IntNumbers,',')

      select  @returnstring = Replace(@returnstring, itemz,REVERSE(itemz))from @RevStrings
    RETURN @returnstring
END

サンプル文字列

select  [dbo].[GetReverseNumberFromString]('Tt123H3451end')

結果

Tt321H1543end

アップデート :

分割機能がない場合は、最初に作成します。以下に含めました

create FUNCTION Split
(    
      @Input NVARCHAR(MAX),
      @Character CHAR(1)
)
RETURNS @Output TABLE (
      Items NVARCHAR(1000)
)
AS
BEGIN
      DECLARE @StartIndex INT, @EndIndex INT

      SET @StartIndex = 1
      IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
      BEGIN
            SET @Input = @Input + @Character
      END

      WHILE CHARINDEX(@Character, @Input) > 0
      BEGIN
            SET @EndIndex = CHARINDEX(@Character, @Input)

            INSERT INTO @Output(Items)
            SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

            SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
      END

      RETURN
END
GO
于 2015-06-02T11:53:53.163 に答える
1

この助けを願っています:

declare @s nvarchar(128) ='Test321Hello'
declare @numStart as int, @numEnd as int
select @numStart =patindex('%[0-9]%',@s)
select @numEnd=len(@s)-patindex('%[0-9]%',REVERSE(@s))
select 
SUBSTRING(@s,0,@numstart)+
reverse(SUBSTRING(@s,@numstart,@numend-@numstart+2))+
SUBSTRING(@s,@numend+2,len(@s)-@numend)
于 2015-06-02T11:02:00.177 に答える
0

これは、あなたが求めている特定の文字列を行います:

select 
substring('Test123Hello',1,4)
+
reverse(substring('Test123Hello',5,3))
+
substring('Test123Hello',8,5)

残りの値から判断すると、取得する英数字パターンのテンプレートを作成する必要があるようです。たとえば、次の形状を持つ任意の値に上記を適用します。

select * from [B&A] where [before] like '[a-z][a-z][a-z][a-z][0-9][0-9][0-9]
[a-z][a-z][a-z][a-z][a-z]'

つまり、値 (前と後) をテーブル [B&A] に入れ、列を「前」と「後」と呼んだ場合、これを実行します。

select 
substring(before,1,4)
+
reverse(substring(before,5,3))
+
substring(before,8,5) as [after]
from [B&A] where [before] like '[a-z][a-z][a-z][a-z][0-9][0-9][0-9][a-z]
[a-z][a-z][a-z][a-z]'

次に、「Test321Hello」が表示されます。

ただし、各英数字形状に対して同様の「[0-9][az]」タイプのテンプレートを作成し、これを [B&A] テーブルに適用しない限り、他の 3 行は影響を受けません。結果を一時テーブルまたは別のテーブルに選択する必要があります。

各テンプレートを順番に適用すると、そのほとんどが取得され、影響を受けなかった行の数を確認し、英数字の形状を確認して、さらにテンプレートを作成する必要があります。最終的に、実行するとすべての可能な組み合わせをキャプチャする一連のコードが得られます。

[az] と [0-9] のすべての可能な組み合わせをキャプチャするこの方法でコードを設計することができます。多くは、扱う文字の最大数に依存します。

于 2015-06-02T09:36:36.053 に答える