Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

SQL Server :opérateur + (unaire) sur des chaînes non numériques

Voici ma propre réponse à cette question (veuillez également consulter la mise à jour à la fin) :

Non, il n'y a pas un tel opérateur unaire défini sur les expressions String. Il est possible que ce soit un bug.

Explication :

L'instruction donnée est valide et génère le résultat ci-dessous :

(No column name) 
----------------
ABCDEF
(1 row(s) affected)

ce qui équivaut à faire le SELECT déclaration sans utiliser le + signe :

SELECT  'ABCDEF'

Être compilé sans donner d'erreurs, en fait être exécuté avec succès, donne l'impression que + fonctionne comme un Unary opération sur la chaîne donnée. Cependant, dans le T-SQL officiel documentation, il n'y a aucune mention d'un tel opérateur. En fait, dans la section intitulée "Opérateurs de chaîne ", + apparaît dans deux opérations String qui sont + (String Concatenation) et += (String Concatenation); mais ni l'un ni l'autre n'est un Unary opération. Également, dans la section intitulée "Opérateurs unaires ", trois opérateurs ont été introduits, un seul d'entre eux étant le + (Positive) opérateur. Cependant, pour ce seul qui semble être pertinent, il devient vite clair que cet opérateur, lui non plus, n'a rien à voir avec les valeurs de chaîne non numériques comme explication de + (Positive) L'opérateur indique explicitement que cet opérateur s'applique uniquement aux valeurs numériques :"Retourne la valeur d'une expression numérique (un opérateur unaire) ".

Peut-être que cet opérateur est là pour accepter avec succès les valeurs de chaîne qui sont évaluées avec succès comme des nombres tels que celui qui a été utilisé ici :

SELECT  +'12345'+1

Lorsque l'instruction ci-dessus est exécutée, elle génère un nombre dans la sortie qui est la somme de la chaîne donnée évaluée comme un nombre et de la valeur numérique qui lui est ajoutée, qui est 1 ici mais cela pourrait évidemment être n'importe quel autre montant :

(No column name) 
----------------
12346
(1 row(s) affected)

Cependant, je doute que cette explication soit correcte car elle soulève les questions ci-dessous :

Premièrement, si nous acceptons que cette explication est vraie, alors nous pouvons conclure que des expressions telles que +'12345' sont évalués en chiffres. Si oui, alors pourquoi ces nombres peuvent-ils apparaître dans les fonctions liées à la chaîne telles que DATALENGTH , LEN , etc. Vous pourriez voir une déclaration comme celle-ci :

  SELECT  DATALENGTH(+'12345')

est tout à fait valide et il en résulte ce qui suit :

 (No column name) 
----------------
5
(1 row(s) affected)

ce qui signifie +'12345' est évalué comme une chaîne et non comme un nombre. Comment cela peut-il s'expliquer ?

Deuxièmement, alors que des déclarations similaires avec - opérateur, tel que celui-ci :

 `SELECT  -'ABCDE'` 

ou même ceci :

`SELECT  -'12345'` 

générer l'erreur ci-dessous :

Invalid operator for data type. Operator equals minus, type equals varchar.

Pourquoi, ne devrait-il pas générer une erreur pour des cas similaires lorsque + l'opérateur a été utilisé à tort avec une valeur de chaîne non numérique ?

Donc, ces deux questions m'empêchent d'accepter l'explication qu'il s'agit du même + (unary) opérateur qui a été introduit dans la documentation pour les valeurs numériques. Comme il n'y en a aucune autre mention ailleurs, il se pourrait qu'il soit délibérément ajouté à la langue. Peut être un bug.

Le problème semble être plus grave lorsque nous constatons qu'aucune erreur n'est générée pour des instructions telles que celle-ci :

SELECT ++++++++'ABCDE'

Je ne sais pas s'il existe d'autres langages de programmation qui acceptent ce genre d'instructions. Mais s'il y en a, ce serait bien de savoir dans quel(s) but(s) ils utilisent un + (unary) Opérateur appliqué à une chaîne. Je ne peux imaginer aucune utilisation!

MISE À JOUR

Ici, il est indiqué qu'il s'agissait d'un bogue dans les versions antérieures, mais qu'il ne sera pas corrigé en raison de la rétrocompatibilité :

Après quelques recherches, ce comportement est voulu puisque + est un opérateur unaire. Ainsi, l'analyseur accepte "+ , et le '+' est simplement ignoré dans ce cas. La modification de ce comportement a de nombreuses implications sur la compatibilité descendante, nous n'avons donc pas l'intention de le modifier et le correctif introduira des modifications inutiles pour le code de l'application.