SQL Server EXEC with unquoted string parameter is valid?










2















By accident I called a stored procedure with an unquoted string parameter. I expected a syntax error as per:



EXECUTE (Transact-SQL)




If the value of a parameter is an object name, character string, or qualified by a database name or schema name, the whole name must be enclosed in single quotation marks.




but this works:



CREATE PROC foobar @a VARCHAR(40) AS BEGIN SELECT @a END
go
EXEC foobar @a = abc


Which surprised me! I tried on SQL Server versions 2008, 2012 and 2016. Am I missing something or is this just an undocumented "feature"?










share|improve this question



















  • 1





    Sounds odd to me too... but I get the same result (tested on SQL Server 2008 R2)

    – JohnLBevan
    Nov 15 '18 at 14:15






  • 1





    And works for multiple parameters too. File it away with "annoying tricks to confound people with" and possibly "things to consider when trying to find a new angle on SQL injection"

    – Damien_The_Unbeliever
    Nov 15 '18 at 14:16







  • 1





    foobar abc on its own would do the same. I can remember a MSDN Connect item relating to this where the conclusion was basically "yes it does this for no specified reason and won't change for compatibility reasons" - but that site is no more.

    – Alex K.
    Nov 15 '18 at 14:19







  • 2





    Yes, this is one of T-SQL's more awful syntactical oversights. It gets extra fun when you think you can pass things like GETDATE. You can, it's just not what you think it is... This also "works" when specifying default values in parameter declarations, and probably in a few more spots where it's not wanted.

    – Jeroen Mostert
    Nov 15 '18 at 14:22







  • 1





    This is pure speculation on my part, but I think this is a result of a lax parsing of object names. That is, making something like sp_helptext [sp_helptext] work "naturally" without having to "redundantly" quote the object names as strings (and this syntax is actually still really used in some system stored procedures, so "not removed for compat reasons" is very valid). If we dig really deep we may well find this was already present in the Sybase original.

    – Jeroen Mostert
    Nov 15 '18 at 14:29















2















By accident I called a stored procedure with an unquoted string parameter. I expected a syntax error as per:



EXECUTE (Transact-SQL)




If the value of a parameter is an object name, character string, or qualified by a database name or schema name, the whole name must be enclosed in single quotation marks.




but this works:



CREATE PROC foobar @a VARCHAR(40) AS BEGIN SELECT @a END
go
EXEC foobar @a = abc


Which surprised me! I tried on SQL Server versions 2008, 2012 and 2016. Am I missing something or is this just an undocumented "feature"?










share|improve this question



















  • 1





    Sounds odd to me too... but I get the same result (tested on SQL Server 2008 R2)

    – JohnLBevan
    Nov 15 '18 at 14:15






  • 1





    And works for multiple parameters too. File it away with "annoying tricks to confound people with" and possibly "things to consider when trying to find a new angle on SQL injection"

    – Damien_The_Unbeliever
    Nov 15 '18 at 14:16







  • 1





    foobar abc on its own would do the same. I can remember a MSDN Connect item relating to this where the conclusion was basically "yes it does this for no specified reason and won't change for compatibility reasons" - but that site is no more.

    – Alex K.
    Nov 15 '18 at 14:19







  • 2





    Yes, this is one of T-SQL's more awful syntactical oversights. It gets extra fun when you think you can pass things like GETDATE. You can, it's just not what you think it is... This also "works" when specifying default values in parameter declarations, and probably in a few more spots where it's not wanted.

    – Jeroen Mostert
    Nov 15 '18 at 14:22







  • 1





    This is pure speculation on my part, but I think this is a result of a lax parsing of object names. That is, making something like sp_helptext [sp_helptext] work "naturally" without having to "redundantly" quote the object names as strings (and this syntax is actually still really used in some system stored procedures, so "not removed for compat reasons" is very valid). If we dig really deep we may well find this was already present in the Sybase original.

    – Jeroen Mostert
    Nov 15 '18 at 14:29













2












2








2


0






By accident I called a stored procedure with an unquoted string parameter. I expected a syntax error as per:



EXECUTE (Transact-SQL)




If the value of a parameter is an object name, character string, or qualified by a database name or schema name, the whole name must be enclosed in single quotation marks.




but this works:



CREATE PROC foobar @a VARCHAR(40) AS BEGIN SELECT @a END
go
EXEC foobar @a = abc


Which surprised me! I tried on SQL Server versions 2008, 2012 and 2016. Am I missing something or is this just an undocumented "feature"?










share|improve this question
















By accident I called a stored procedure with an unquoted string parameter. I expected a syntax error as per:



EXECUTE (Transact-SQL)




If the value of a parameter is an object name, character string, or qualified by a database name or schema name, the whole name must be enclosed in single quotation marks.




but this works:



CREATE PROC foobar @a VARCHAR(40) AS BEGIN SELECT @a END
go
EXEC foobar @a = abc


Which surprised me! I tried on SQL Server versions 2008, 2012 and 2016. Am I missing something or is this just an undocumented "feature"?







sql-server






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 14:11









Sami

9,05831243




9,05831243










asked Nov 15 '18 at 14:10









user1443098user1443098

1,69511126




1,69511126







  • 1





    Sounds odd to me too... but I get the same result (tested on SQL Server 2008 R2)

    – JohnLBevan
    Nov 15 '18 at 14:15






  • 1





    And works for multiple parameters too. File it away with "annoying tricks to confound people with" and possibly "things to consider when trying to find a new angle on SQL injection"

    – Damien_The_Unbeliever
    Nov 15 '18 at 14:16







  • 1





    foobar abc on its own would do the same. I can remember a MSDN Connect item relating to this where the conclusion was basically "yes it does this for no specified reason and won't change for compatibility reasons" - but that site is no more.

    – Alex K.
    Nov 15 '18 at 14:19







  • 2





    Yes, this is one of T-SQL's more awful syntactical oversights. It gets extra fun when you think you can pass things like GETDATE. You can, it's just not what you think it is... This also "works" when specifying default values in parameter declarations, and probably in a few more spots where it's not wanted.

    – Jeroen Mostert
    Nov 15 '18 at 14:22







  • 1





    This is pure speculation on my part, but I think this is a result of a lax parsing of object names. That is, making something like sp_helptext [sp_helptext] work "naturally" without having to "redundantly" quote the object names as strings (and this syntax is actually still really used in some system stored procedures, so "not removed for compat reasons" is very valid). If we dig really deep we may well find this was already present in the Sybase original.

    – Jeroen Mostert
    Nov 15 '18 at 14:29












  • 1





    Sounds odd to me too... but I get the same result (tested on SQL Server 2008 R2)

    – JohnLBevan
    Nov 15 '18 at 14:15






  • 1





    And works for multiple parameters too. File it away with "annoying tricks to confound people with" and possibly "things to consider when trying to find a new angle on SQL injection"

    – Damien_The_Unbeliever
    Nov 15 '18 at 14:16







  • 1





    foobar abc on its own would do the same. I can remember a MSDN Connect item relating to this where the conclusion was basically "yes it does this for no specified reason and won't change for compatibility reasons" - but that site is no more.

    – Alex K.
    Nov 15 '18 at 14:19







  • 2





    Yes, this is one of T-SQL's more awful syntactical oversights. It gets extra fun when you think you can pass things like GETDATE. You can, it's just not what you think it is... This also "works" when specifying default values in parameter declarations, and probably in a few more spots where it's not wanted.

    – Jeroen Mostert
    Nov 15 '18 at 14:22







  • 1





    This is pure speculation on my part, but I think this is a result of a lax parsing of object names. That is, making something like sp_helptext [sp_helptext] work "naturally" without having to "redundantly" quote the object names as strings (and this syntax is actually still really used in some system stored procedures, so "not removed for compat reasons" is very valid). If we dig really deep we may well find this was already present in the Sybase original.

    – Jeroen Mostert
    Nov 15 '18 at 14:29







1




1





Sounds odd to me too... but I get the same result (tested on SQL Server 2008 R2)

– JohnLBevan
Nov 15 '18 at 14:15





Sounds odd to me too... but I get the same result (tested on SQL Server 2008 R2)

– JohnLBevan
Nov 15 '18 at 14:15




1




1





And works for multiple parameters too. File it away with "annoying tricks to confound people with" and possibly "things to consider when trying to find a new angle on SQL injection"

– Damien_The_Unbeliever
Nov 15 '18 at 14:16






And works for multiple parameters too. File it away with "annoying tricks to confound people with" and possibly "things to consider when trying to find a new angle on SQL injection"

– Damien_The_Unbeliever
Nov 15 '18 at 14:16





1




1





foobar abc on its own would do the same. I can remember a MSDN Connect item relating to this where the conclusion was basically "yes it does this for no specified reason and won't change for compatibility reasons" - but that site is no more.

– Alex K.
Nov 15 '18 at 14:19






foobar abc on its own would do the same. I can remember a MSDN Connect item relating to this where the conclusion was basically "yes it does this for no specified reason and won't change for compatibility reasons" - but that site is no more.

– Alex K.
Nov 15 '18 at 14:19





2




2





Yes, this is one of T-SQL's more awful syntactical oversights. It gets extra fun when you think you can pass things like GETDATE. You can, it's just not what you think it is... This also "works" when specifying default values in parameter declarations, and probably in a few more spots where it's not wanted.

– Jeroen Mostert
Nov 15 '18 at 14:22






Yes, this is one of T-SQL's more awful syntactical oversights. It gets extra fun when you think you can pass things like GETDATE. You can, it's just not what you think it is... This also "works" when specifying default values in parameter declarations, and probably in a few more spots where it's not wanted.

– Jeroen Mostert
Nov 15 '18 at 14:22





1




1





This is pure speculation on my part, but I think this is a result of a lax parsing of object names. That is, making something like sp_helptext [sp_helptext] work "naturally" without having to "redundantly" quote the object names as strings (and this syntax is actually still really used in some system stored procedures, so "not removed for compat reasons" is very valid). If we dig really deep we may well find this was already present in the Sybase original.

– Jeroen Mostert
Nov 15 '18 at 14:29





This is pure speculation on my part, but I think this is a result of a lax parsing of object names. That is, making something like sp_helptext [sp_helptext] work "naturally" without having to "redundantly" quote the object names as strings (and this syntax is actually still really used in some system stored procedures, so "not removed for compat reasons" is very valid). If we dig really deep we may well find this was already present in the Sybase original.

– Jeroen Mostert
Nov 15 '18 at 14:29












1 Answer
1






active

oldest

votes


















4














MS are aware, and their comments on this post imply that this is by design:




SQL Server automatically converts “single-word identifiers” to string literals if they are provided as NVARCHAR parameters in stored procedure calls. Therefore these statement will work fine:



EXEC dbo.TestProc foo
EXEC dbo.TestProc "foo"
EXEC dbo.TestProc [foo]


and they are equivalent to:



EXEC dbo.TestProc 'foo'


However, it does not convert identifiers to string literals in SELECT and assignments.




However, I can't think of any situation where it would be appropriate to use this (aside from testing for vulnerabilities which exploit this feature, or in writing code to execute user-provided queries which you wish to provide full language support for, including quirks.



The best advise is to be aware that this is possible (so you don't rule out the possibility of it working when writing tests / debugging code / checking for potential exploits), but do not make use of this behavior in your own code.






share|improve this answer


















  • 1





    Plus 1 on the advice. I'd never let it pass in code review.

    – user1443098
    Nov 15 '18 at 14:48










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53321308%2fsql-server-exec-with-unquoted-string-parameter-is-valid%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














MS are aware, and their comments on this post imply that this is by design:




SQL Server automatically converts “single-word identifiers” to string literals if they are provided as NVARCHAR parameters in stored procedure calls. Therefore these statement will work fine:



EXEC dbo.TestProc foo
EXEC dbo.TestProc "foo"
EXEC dbo.TestProc [foo]


and they are equivalent to:



EXEC dbo.TestProc 'foo'


However, it does not convert identifiers to string literals in SELECT and assignments.




However, I can't think of any situation where it would be appropriate to use this (aside from testing for vulnerabilities which exploit this feature, or in writing code to execute user-provided queries which you wish to provide full language support for, including quirks.



The best advise is to be aware that this is possible (so you don't rule out the possibility of it working when writing tests / debugging code / checking for potential exploits), but do not make use of this behavior in your own code.






share|improve this answer


















  • 1





    Plus 1 on the advice. I'd never let it pass in code review.

    – user1443098
    Nov 15 '18 at 14:48















4














MS are aware, and their comments on this post imply that this is by design:




SQL Server automatically converts “single-word identifiers” to string literals if they are provided as NVARCHAR parameters in stored procedure calls. Therefore these statement will work fine:



EXEC dbo.TestProc foo
EXEC dbo.TestProc "foo"
EXEC dbo.TestProc [foo]


and they are equivalent to:



EXEC dbo.TestProc 'foo'


However, it does not convert identifiers to string literals in SELECT and assignments.




However, I can't think of any situation where it would be appropriate to use this (aside from testing for vulnerabilities which exploit this feature, or in writing code to execute user-provided queries which you wish to provide full language support for, including quirks.



The best advise is to be aware that this is possible (so you don't rule out the possibility of it working when writing tests / debugging code / checking for potential exploits), but do not make use of this behavior in your own code.






share|improve this answer


















  • 1





    Plus 1 on the advice. I'd never let it pass in code review.

    – user1443098
    Nov 15 '18 at 14:48













4












4








4







MS are aware, and their comments on this post imply that this is by design:




SQL Server automatically converts “single-word identifiers” to string literals if they are provided as NVARCHAR parameters in stored procedure calls. Therefore these statement will work fine:



EXEC dbo.TestProc foo
EXEC dbo.TestProc "foo"
EXEC dbo.TestProc [foo]


and they are equivalent to:



EXEC dbo.TestProc 'foo'


However, it does not convert identifiers to string literals in SELECT and assignments.




However, I can't think of any situation where it would be appropriate to use this (aside from testing for vulnerabilities which exploit this feature, or in writing code to execute user-provided queries which you wish to provide full language support for, including quirks.



The best advise is to be aware that this is possible (so you don't rule out the possibility of it working when writing tests / debugging code / checking for potential exploits), but do not make use of this behavior in your own code.






share|improve this answer













MS are aware, and their comments on this post imply that this is by design:




SQL Server automatically converts “single-word identifiers” to string literals if they are provided as NVARCHAR parameters in stored procedure calls. Therefore these statement will work fine:



EXEC dbo.TestProc foo
EXEC dbo.TestProc "foo"
EXEC dbo.TestProc [foo]


and they are equivalent to:



EXEC dbo.TestProc 'foo'


However, it does not convert identifiers to string literals in SELECT and assignments.




However, I can't think of any situation where it would be appropriate to use this (aside from testing for vulnerabilities which exploit this feature, or in writing code to execute user-provided queries which you wish to provide full language support for, including quirks.



The best advise is to be aware that this is possible (so you don't rule out the possibility of it working when writing tests / debugging code / checking for potential exploits), but do not make use of this behavior in your own code.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 15 '18 at 14:34









JohnLBevanJohnLBevan

14.6k146111




14.6k146111







  • 1





    Plus 1 on the advice. I'd never let it pass in code review.

    – user1443098
    Nov 15 '18 at 14:48












  • 1





    Plus 1 on the advice. I'd never let it pass in code review.

    – user1443098
    Nov 15 '18 at 14:48







1




1





Plus 1 on the advice. I'd never let it pass in code review.

– user1443098
Nov 15 '18 at 14:48





Plus 1 on the advice. I'd never let it pass in code review.

– user1443098
Nov 15 '18 at 14:48



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53321308%2fsql-server-exec-with-unquoted-string-parameter-is-valid%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3

Museum of Modern and Contemporary Art of Trento and Rovereto