sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server:+(unär) operator på icke-numeriska strängar

Här är mitt eget svar på denna fråga (se även uppdateringen i slutet):

Nej, det finns inte en sådan unär operator definierad på String-uttrycken. Det är möjligt att detta är en bugg.

Förklaring:

Det givna uttalandet är giltigt och det genererar följande resultat:

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

vilket motsvarar att göra SELECT utan att använda + tecken:

SELECT  'ABCDEF'

Att kompileras utan att ge några fel, faktiskt exekveras framgångsrikt, ger intrycket att + fungerar som en Unary operation på den givna strängen. Men i den officiella T-SQL dokumentation, finns det inget omnämnande av en sådan operatör. Faktum är att i avsnittet "Strängoperatörer ", + visas i två strängoperationer som är + (String Concatenation) och += (String Concatenation); men inte heller en Unary drift. Även i avsnittet "Unary Operators ", tre operatorer har introducerats, bara en av dem är + (Positive) operatör. Men för denna enda som verkar vara relevant, blir det snart klart att även denna operator inte har något att göra med icke-numeriska strängvärden som förklaringen till + (Positive) operatorn anger uttryckligen att denna operator endast är tillämplig för numeriska värden:"Returnerar värdet av ett numeriskt uttryck (en unär operator) ".

Kanske är den här operatorn där för att framgångsrikt acceptera de strängvärden som framgångsrikt utvärderas som siffror, till exempel den som har använts här:

SELECT  +'12345'+1

När ovanstående sats exekveras genererar den ett tal i utdata som är summan av både den givna strängen utvärderad som ett tal och det numeriska värdet som läggs till den, vilket är 1 här men det kan uppenbarligen vara vilken annan summa som helst:

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

Jag tvivlar dock på att denna förklaring är korrekt eftersom den väcker följande frågor:

För det första, om vi accepterar att denna förklaring är sann, kan vi dra slutsatsen att uttryck som +'12345' utvärderas till siffror. Om så är fallet, varför är det så att dessa siffror kan visas i strängrelaterade funktioner som DATALENGTH , LEN , etc. Du kan se ett uttalande som detta:

  SELECT  DATALENGTH(+'12345')

är ganska giltig och det resulterar i följande:

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

vilket betyder +'12345' utvärderas som en sträng inte ett nummer. Hur kan detta förklaras?

För det andra, medan liknande uttalanden med - operator, som denna:

 `SELECT  -'ABCDE'` 

eller till och med detta:

`SELECT  -'12345'` 

generera nedanstående fel:

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

Varför, borde det inte generera ett fel för liknande fall när + har operatorn använts felaktigt med ett icke-numeriskt strängvärde?

Så dessa två frågor hindrar mig från att acceptera förklaringen att detta är samma + (unary) operator som har införts i dokumentationen för numeriska värden. Eftersom det inte nämns någon annanstans kan det vara så att det medvetet läggs till språket. Kan vara en bugg.

Problemet ser ut att vara allvarligare när vi ser att inget fel genereras för uttalanden som det här heller:

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

Jag vet inte om det finns några andra programmeringsspråk där ute som accepterar den här typen av påståenden. Men om det finns det skulle det vara trevligt att veta i vilket syfte de använder en + (unary) operatorn applicerad på en sträng. Jag kan inte föreställa mig någon användning!

UPPDATERA

Här står det att detta har varit ett fel i tidigare versioner men det kommer inte att fixas på grund av bakåtkompatibilitet:

Efter en del undersökningar är detta beteende genom design eftersom + är en unär operator. Så parsern accepterar "+, och "+" ignoreras helt enkelt i det här fallet. Att ändra detta beteende har många bakåtkompatibilitetsimplikationer så vi har inte för avsikt att ändra det och korrigeringen kommer att införa onödiga ändringar för applikationskoden.




  1. Hur ansluter man till fjärrstyrd Oracle DB med PL/SQL-utvecklare?

  2. Det går inte att skapa en databastabell med namnet "användare" i PostgreSQL

  3. Bygga Android-app för att köra PHP och MySQL på Android-surfplatta

  4. Är mysql_insert_id säkert att använda?