0

I’ve learned that FORMATMESSAGE() is the closest thing to parameterising a string in SQL Server. So this works for me:

DECLARE @db NVARCHAR(12) = 'test';
SELECT formatmessage(N'USE master; DROP DATABASE IF EXISTS %s;', @db);

I also know that you can execute a constructed string using EXECUTE():

DECLARE @db NVARCHAR(12) = 'test';
EXECUTE(N'USE master; DROP DATABASE IF EXISTS ' + @db);

It seems to me that you should be able to combine the two as follows:

DECLARE @db NVARCHAR(12) = 'test';
EXECUTE(formatmessage(N'USE master; DROP DATABASE IF EXISTS %s;', @db));

That doesn’t work. I get the error message:

Incorrect syntax near 'formatmessage'.

Is there a trick to using FORMATMESSAGE with EXECUTE?

Note

This question has been closed because somebody thinks it’s the same as Why does concatenating strings in the argument of EXEC sometimes cause a syntax error in T-SQL? .

The solution may be the same (EXECUTE doesn’t allow expressions with function calls) but:

  • The question is different (concerning FORMATMESSAGE() rather than concatenation), so anybody looking for a solution (such as I) won’t naturally think that the other question is relevant.
  • Neither the answer to the other question nor the referenced documentation makes it clear that the string can be evaluated, such as concatenation, but not if it includes a function call.
12
  • @DaleK I can’t see that the document excludes evaluation specifically. Doesn’t the expression N'DROP DATABASE IF EXISTS ' + @db also require evaluation?
    – Manngo
    Commented 5 hours ago
  • @DaleK I see it now. You can use basic operators, but not functions. Can you write this as an answer so I can accept it?
    – Manngo
    Commented 5 hours ago
  • "Ive learned that FORMATMESSAGE() is the closest thing to parameterising a string in SQL Server." It's really not any better than just injecting the value. Stick to parameterising parameters and using sys.sp_executesql and safely inject your objects by validating that and using QUOTENAME. FORMATMESSAGE does nothing to stop injection attacks
    – Thom A
    Commented 3 hours ago
  • As you can see, FORMATMESSAGE does nothing do stop the injection: db<>fiddle.
    – Thom A
    Commented 2 hours ago
  • It's also worth noting that FORMATMESSAGE is limited to returning 2,047 characters, @siggemannen ; a string of 2,048 or more will be truncated to 2,044 characters followed by .... For larger dynamic scripts, you will quickly run into truncation issues.
    – Thom A
    Commented 1 hour ago

1 Answer 1

-1

You're on the right track but in SQL Server, EXECUTE() does not validate expressions like FORMATMESSAGE(), as these are not allowed directly. But to use them both together a variable can be used to hold the result of FORMATMESSAGE() first, then pass that variable to EXECUTE().

New contributor
manav jain is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
2
  • 1
    A reference to the documentation would improve this answer.
    – Dale K
    Commented 5 hours ago
  • This is poor advice, as the problem of injection remains. It might work, but it's not a good solution; it's just as dangerous as raw injection.
    – Thom A
    Commented 2 hours ago

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.