sql >> Databáze >  >> RDS >> Sqlserver

SQL Server:+(unární) operátor na nenumerických řetězcích

Zde je moje vlastní odpověď na tuto otázku (viz také aktualizaci na konci):

Ne, takový unární operátor ve výrazech String není definován. Je možné, že se jedná o chybu.

Vysvětlení:

Daný příkaz je platný a generuje níže uvedený výsledek:

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

což je ekvivalentní provedení SELECT bez použití + znak:

SELECT  'ABCDEF'

Být zkompilován bez uvedení jakýchkoli chyb, ve skutečnosti úspěšně proveden, vyvolává dojem, že + funguje jako Unary operace na daném řetězci. Nicméně v oficiálním T-SQL dokumentace, není o takovém provozovateli ani zmínka. Ve skutečnosti v části nazvané "Operátoři řetězců “, + se objeví ve dvou operacích s řetězci, které jsou + (String Concatenation) a += (String Concatenation); ale ani jeden není Unary úkon. Také v části nazvané "Unární operátoři “, byly zavedeny tři operátory, pouze jeden z nich je + (Positive) operátor. Avšak pro tento jediný, který se zdá být relevantní, je brzy jasné, že ani tento operátor nemá nic společného s nečíselnými hodnotami řetězce jako vysvětlení pro + (Positive) operátor výslovně uvádí, že tento operátor je použitelný pouze pro číselné hodnoty:"Vrátí hodnotu číselného výrazu (unární operátor) ".

."

Možná je zde tento operátor proto, aby úspěšně přijal ty řetězcové hodnoty, které jsou úspěšně vyhodnoceny jako čísla, jako je to, které bylo použito zde:

SELECT  +'12345'+1

Po provedení výše uvedeného příkazu vygeneruje na výstupu číslo, které je součtem daného řetězce vyhodnoceného jako číslo a číselné hodnoty k němu přidané, což je 1 zde, ale samozřejmě to může být jakákoli jiná částka:

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

Pochybuji však, že toto vysvětlení je správné, protože vyvolává níže uvedené otázky:

Za prvé, pokud připustíme, že toto vysvětlení je pravdivé, pak můžeme dojít k závěru, že výrazy jako +'12345' jsou vyhodnoceny na čísla. Pokud ano, proč se tato čísla mohou objevit ve funkcích souvisejících s řetězci, jako je DATALENGTH , LEN , atd. Můžete vidět prohlášení, jako je toto:

  SELECT  DATALENGTH(+'12345')

je zcela platný a jeho výsledkem je následující:

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

což znamená +'12345' je vyhodnocen jako řetězec, nikoli jako číslo. Jak to lze vysvětlit?

Za druhé, zatímco podobné příkazy s - operátor, jako je tento:

 `SELECT  -'ABCDE'` 

nebo dokonce toto:

`SELECT  -'12345'` 

vygenerovat níže uvedenou chybu:

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

Proč, neměl by v podobných případech vygenerovat chybu, když + byl operátor nesprávně použit s nečíselnou hodnotou řetězce?

Tyto dvě otázky mi tedy brání přijmout vysvětlení, že se jedná o totéž + (unary) operátor, který byl zaveden v dokumentaci pro číselné hodnoty. Protože o něm není nikde jinde zmínka, může se stát, že je do jazyka záměrně přidán. Může to být chyba.

Problém se zdá být závažnější, když vidíme, že se ani u příkazů, jako je tento, negeneruje žádná chyba:

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

Nevím, jestli existují nějaké jiné programovací jazyky, které přijímají tento druh prohlášení. Ale pokud existují, bylo by hezké vědět, k jakému účelu (účelům) používají + (unary) operátor použitý na řetězec. Neumím si představit žádné využití!

AKTUALIZACE

Zde se píše, že to byla chyba v dřívějších verzích, ale nebude opravena kvůli zpětné kompatibilitě:

Po určitém vyšetřování je toto chování záměrné protože + je unární operátor. Analyzátor tedy akceptuje "+ a '+' je v tomto případě jednoduše ignorováno. Změna tohoto chování má mnoho důsledků pro zpětnou kompatibilitu, takže ji nehodláme měnit a oprava zavede zbytečné změny v kódu aplikace.




  1. Načíst hierarchii z tabulky, jako je tato

  2. automaticky aktualizuje pole mysql na základě hodnoty jiného pole

  3. Oracle kurzor pro přiřazení

  4. Náhodný PRIMÁRNÍ KLÍČ pro Innodb