web-dev-qa-db-ja.com

EXECに対して関数を実行できません

私のSQL Serverの本では、EXEC内で関数を実行することはできず、例を示しています。

_DECLARE @NumberOfLetters int = 15;
EXEC(‘SELECT LEFT(Name,’ + CAST(@NumberOfLetters AS varchar)
 + ‘) AS ShortName FROM Production.Product’);
_

EXEC行の前にCAST()関数を完全に解決する必要があるため、これは機能せず、コードを次のように変更できます。

_DECLARE @NumberOfLetters AS int = 15;
DECLARE @str AS varchar(255);
SET @str = ‘SELECT LEFT(Name,’ + CAST(@NumberOfLetters AS varchar) + ‘) AS ShortName FROM Production.Product’;
EXEC(@str);
_

今回は、前述のように、EXEC行の前にCAST()関数を完全に解決する必要があるため、機能します。

しかし、もう1つ質問があります。LEFT()関数はどうですか、なぜEXECに対して実行できるのですか?

5
slowjams

例のLEFT()関数は、EXECステートメントの一部ではありません。これは、EXECステートメントによって実行される動的SQLの一部を表す文字列の中にあります。

対照的に、CAST()関数はbuildの文字列に使用されます。正しい引用符を使用する場合、_'_&__ではなく__を使用すると、構文の強調表示の違いも確認できます。

_DECLARE @NumberOfLetters int = 15;
EXEC('SELECT LEFT(Name,' + CAST(@NumberOfLetters AS varchar)
 + ') AS ShortName FROM Production.Product');
_

構文の強調表示がモニターで正しく表示される場合は、LEFTキーワードが文字列の一部として赤で表示され、名前CASTが別の色で表示されていることがわかります。 、これは文字列の一部ではなく、文字列の作成に使用されるの一部であるためです。それがまさに問題です。EXEC (...)は式を受け入れません。 (単一の)文字列リテラルまたは文字列変数のいずれかのみを受け入れます。

一部の値(この場合は_@NumberOfLetters_値)に基づいて動的SQLスクリプトを作成する必要があるため、変数を使用する必要があります。ビルドされたスクリプトをそこに保存してから、それをEXECステートメントに渡して動的スクリプトを実行します。これが、変更されたコードが行うことです。

_DECLARE @NumberOfLetters AS int = 15;
DECLARE @str AS varchar(255);

-- you build the dynamic script first and store it in a variable
SET @str = 'SELECT LEFT(Name,' + CAST(@NumberOfLetters AS varchar)
         + ') AS ShortName FROM Production.Product';

-- then you just pass the variable to EXEC to run the dynamic script
EXEC(@str);
_
7
Andriy M