web-dev-qa-db-fra.com

Sous-chaîne sans les n premiers caractères

Je développe une procédure stockée SQL Server 2016 et je souhaite obtenir les derniers caractères d'une colonne varchar(38).

Je sais qu'il y aura toujours au moins 18 caractères et je ne connais pas la longueur exacte de la colonne, car elle est variable.

Je pense que je peux obtenir la longueur de la colonne et faire une soustraction pour utiliser SUBSTRING, mais je ne peux pas le faire car je fais ceci:

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

Je génère un JSON et je ne sais pas comment obtenir la longueur de chaque colonne Serial dans une sélection.

Ma question est: comment puis-je obtenir une sous-chaîne d'une chaîne sans les 18 premiers caractères sans connaître sa longueur?

Une solution pourrait être:

SUBSTRING(Serial, 18, 38)

Et il renvoie toujours la sous-chaîne de 18 à la fin de la chaîne même si la chaîne n'a pas une longueur de 38.

5
VansFannel

J'utiliserais:

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

Cela obtient la longueur du champ et en soustrait 18, vous laissant tout après le 18ème caractère.

6
George.Palacios

Votre solution SUBSTRING semble assez bonne, je ne sais pas pourquoi vous auriez besoin de demander plus. Je voudrais seulement noter que si vous voulez sauter les 18 premiers caractères, vous devez spécifier 19 comme deuxième argument pour SUBSTRING, car en SQL les positions des caractères dans une chaîne commencent à 1. Donc, cela fait sens parfait et devrait bien fonctionner pour vous:

SUBSTRING(Serial, 19, 38)

Si vous spécifiez 18, vous sauterez 17 caractères.

La solution utilisant RIGHT et LEN, suggérée par George.Palacios fonctionnera également, mais les résultats de ces deux solutions pourraient ne pas être les mêmes selon que Serial peut avoir des espaces de fin. La raison de la différence possible est que la fonction LEN ignore les espaces de fin, tandis que RIGHT ne le fait pas, ce qui signifie que pour une chaîne avec des espaces de fin, le résultat ne sera probablement pas ce que vous attendez .

Permettez-moi de démontrer que l'utilisation d'un exemple simple avec une chaîne plus courte. Supposons que la longueur maximale soit 10, le nombre de caractères à ignorer est 4 et la chaîne spécifique est 'abcde  '. (Les guillemets ici ne sont que des délimiteurs de chaîne, pour que vous puissiez voir les espaces de fin.) Si vous le faites

SUBSTRING('abcde  ', 5, 10)

tu auras 'e ' comme résultat, car SUBSTRING commencera simplement à couper la chaîne au 5ème caractère et inclura tous les caractères jusqu'à la fin de la chaîne.

En revanche, l'option RIGHT/LEN

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

donnera ' '. La fonction LEN ignorera les deux espaces de fin et renverra 5. La soustraction de 4 à 5 vous donne 1, donc RIGHT renverra juste un caractère à l'extrême droite de la chaîne, qui est un espace.

Comme je l'ai dit, cependant, si Serial ne peut jamais avoir d'espaces de fin, l'une ou l'autre option fera l'affaire. Pour être complet, permettez-moi d'en suggérer une de plus, qui utilise la fonction STUFF:

STUFF(Serial, 1, 18, '')

La fonction STUFF vous permet de supprimer une sous-chaîne et/ou d'en insérer une autre dans une chaîne donnée à une position donnée. Ainsi, pour ignorer 18 caractères à l'aide de cette fonction, vous spécifiez la position de départ 1, 18 caractères à supprimer et une chaîne vide ('') pour les remplacer par. Comme SUBSTRING, cette solution fonctionnera correctement avec les espaces de fin, si vous avez besoin de les prendre en compte.

8
Andriy M