sql >> Base de Datos >  >> RDS >> Sqlserver

SQL Server:operador + (unario) en cadenas no numéricas

Aquí está mi propia respuesta a esta pregunta (consulte también la actualización al final):

No, no existe tal operador unario definido en las expresiones de cadena. Es posible que esto sea un error.

Explicación:

La declaración dada es válida y genera el siguiente resultado:

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

que es equivalente a hacer SELECT declaración sin usar el + firmar:

SELECT  'ABCDEF'

Al compilarse sin dar ningún error, de hecho se ejecuta con éxito, da la impresión de que + está operando como Unary operación en la cadena dada. Sin embargo, en el T-SQL oficial documentación, no se menciona tal operador. De hecho, en la sección titulada "Operadores de cadena ", + aparece en dos operaciones de cadena que son + (String Concatenation) y += (String Concatenation); pero tampoco es un Unary operación. Además, en la sección titulada "Operadores unarios ", se han introducido tres operadores, siendo solo uno de ellos el + (Positive) operador. Sin embargo, para este único que parece ser relevante, pronto queda claro que este operador tampoco tiene nada que ver con valores de cadena no numéricos como la explicación de + (Positive) El operador establece explícitamente que este operador solo se aplica a valores numéricos:"Devuelve el valor de una expresión numérica (un operador unario) ".

Tal vez, este operador esté ahí para aceptar con éxito aquellos valores de cadena que se evalúan con éxito como números como el que se ha utilizado aquí:

SELECT  +'12345'+1

Cuando se ejecuta la declaración anterior, genera un número en la salida que es la suma de la cadena dada evaluada como un número y el valor numérico que se le agrega, que es 1 aquí pero obviamente podría ser cualquier otra cantidad:

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

Sin embargo, dudo que esta explicación sea la correcta, ya que plantea las siguientes preguntas:

En primer lugar, si aceptamos que esta explicación es cierta, podemos concluir que expresiones como +'12345' se evalúan a números. Si es así, ¿por qué estos números pueden aparecer en las funciones relacionadas con cadenas como DATALENGTH? , LEN , etc. Podría ver una declaración como esta:

  SELECT  DATALENGTH(+'12345')

es bastante válido y da como resultado lo siguiente:

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

lo que significa +'12345' se evalúa como una cadena, no como un número. ¿Cómo se puede explicar esto?

En segundo lugar, mientras declaraciones similares con - operador, como este:

 `SELECT  -'ABCDE'` 

o incluso esto:

`SELECT  -'12345'` 

generar el siguiente error:

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

¿Por qué, no debería generar un error para casos similares cuando + ¿El operador se ha utilizado incorrectamente con un valor de cadena no numérico?

Entonces, estas dos preguntas me impiden aceptar la explicación de que este es el mismo + (unary) operador que se ha introducido en la documentación para valores numéricos. Como no se menciona en ningún otro lugar, podría ser que se agregue deliberadamente al idioma. Puede ser un error.

El problema parece ser más grave cuando vemos que no se genera ningún error para declaraciones como esta:

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

No sé si hay otros lenguajes de programación que acepten este tipo de declaraciones. Pero si los hay, sería bueno saber con qué propósito (s) usan un + (unary) operador aplicado a una cadena. ¡No puedo imaginar ningún uso!

ACTUALIZAR

Aquí dice que esto ha sido un error en versiones anteriores, pero no se solucionará debido a la compatibilidad con versiones anteriores:

Después de algunas investigaciones, este comportamiento es por diseño ya que + es un operador unario. Entonces, el analizador acepta "+, y el '+' simplemente se ignora en este caso. Cambiar este comportamiento tiene muchas implicaciones de compatibilidad con versiones anteriores, por lo que no tenemos la intención de cambiarlo y la corrección introducirá cambios innecesarios para el código de la aplicación.