web-dev-qa-db-ja.com

最初のn文字を含まない部分文字列

SQL Server 2016のストアドプロシージャを開発していて、varchar(38)列の最後の文字を取得したいと考えています。

列は常に可変であるため、常に18文字以上あり、列の正確な長さはわかりません。

列の長さを取得してSUBSTRINGを使用するために減算を実行できると思いますが、これを実行しているため、それを実行できません。

set @externalCodes = (
    select Serial, AggregationLevel
      from ExternalCode where ProductionOrderId = @productionOrderId
    for json path

JSONを生成していますが、select内の各Serial列の長さを取得する方法がわかりません。

私の質問は、最初の長さ18文字のない文字列から、その長さを知らずに部分文字列を取得するにはどうすればよいですか?

1つの解決策は次のとおりです。

SUBSTRING(Serial, 18, 38)

また、文字列の長さが38でなくても、常に18から文字列の末尾までの部分文字列を返します。

5
VansFannel

私は使うだろう:

RIGHT(RTRIM(Serial),LEN(Serial)-18) 

これによりフィールドの長さが取得され、フィールドから18が減算され、18番目の文字以降のすべてが残ります。

6
George.Palacios

あなたのSUBSTRINGソリューションは十分に思えますが、なぜこれ以上何かを要求する必要があるのか​​わかりません。最初の18文字をスキップする場合は、SUBSTRINGの2番目の引数として19を指定する必要があります。SQLでは文字列の文字位置が1から始まるため、これは完全に意味があり、機能するはずです。あなたのために:

SUBSTRING(Serial, 19, 38)

18を指定すると、17文字をスキップします。

RIGHTおよびLENGeorge.Palaciosにより推奨 を使用するソリューションも機能しますが、これらの2つのソリューションの結果は、Serialに末尾のスペースがあるかどうかによって異なる場合があります。考えられる違いの理由は、LEN関数が末尾のスペースを無視するのに対し、RIGHTは無視しないことです。つまり、末尾のスペースを含む文字列の場合、結果は期待どおりにならない可能性が高いです。

短い文字列を使用した簡単な例を使用してそのことを示します。最大長が10、スキップする文字数が4で、特定の文字列が'abcde  'であるとします。 (ここでの引用符は、末尾のスペースを確認できるようにするための単なる文字列区切り文字です。)

SUBSTRING('abcde  ', 5, 10)

SUBSTRINGは5番目の文字から文字列の切り取りを開始し、文字列の最後までのすべての文字を含めるため、結果として'e 'が返されます。

対照的に、RIGHT/LENオプション

RIGHT('abcde  ', LEN('abcde  ') - 4)

' 'が生成されます。 LEN関数は、2つの末尾のスペースを無視して5を返します。5から4を引くと1が得られます。したがって、RIGHTは、文字列の右端の1文字だけを返します。これはスペースです。

ただし、先ほど述べたように、Serialに後続スペースを含めることができない場合は、どちらのオプションでも可能です。完全を期すために、STUFF関数を使用してもう1つ提案します。

STUFF(Serial, 1, 18, '')

STUFF関数を使用すると、特定の位置の特定の文字列から部分文字列を削除したり、別の文字列を挿入したりできます。したがって、この関数を使用して18文字をスキップするには、開始位置1を指定して、削除する18文字と、それらを置き換える空の文字列('')を指定します。 SUBSTRINGと同様に、このソリューションは、スペースを考慮に入れる必要がある場合に、末尾のスペースで正しく機能します。

8
Andriy M