views:

206

answers:

6

I'm trying to make my integration tests more idempotent. One idea was to execute rollback after every test, the other idea was to some how programatically parse the text, similar to the green check box in Query Analyzer or SSMS.

How do I get SQL Server to parse my command without running it using ADO.NET?

UPDATE: This is what finally worked as desired:

using (DbCommand executeOnly = Factory.DbCommand())
{
    executeOnly.Connection = command.Connection;
    executeOnly.CommandType = CommandType.Text;
    executeOnly.CommandText = "SET NOEXEC ON;";
    executeOnly.Connection.Open();
    executeOnly.ExecuteNonQuery();
}
//set more properties of command.
command.Execute();

For inexplicable reasons, "SET PARSEONLY ON" only worked in Query Analyzer. I couldn't set this on an ADO.NET connection. It is just as well because PARSEONLY seems to catch only syntax errors, which isn't a common error. SET NOEXEC ON will catch a wider varieties of errors, such as a view that references a missing table or column or a missing parameter in a stored procedure.

+14  A: 

I think the command you are looking for is SET NOEXEC ON. If you set this for your connection, the queries will be parsed but will not be executed. Another option would be SET PARSEONLY ON, but I'm honestly not sure what the difference between the two really is.

Eric Petroelje
+1, [SET NOEXEC (Transact-SQL)](http://msdn.microsoft.com/en-us/library/ms188394.aspx)
KM
+1, I never heard about "SET NOEXEC ON" or "SET PARSEONLY ON". Thanks!
TcKs
Following on from the comments under my answer, I think there could be a bug with SET NOEXEC ON in SQL 2K8 - has been reproduced by others too. Check out the MS Connect bug I've raised: https://connect.microsoft.com/SQLServer/feedback/details/569263/set-noexec-on-does-not-flag-up-invalid-object-name-errors
AdaTheDev
@AdaTheDev from my dinking around, it is clear that neither PARSEONLY or NOEXEC is a very rigorous check. They catch only a narrow set of errors.
MatthewMartin
+3  A: 

SET PARSEONLY : Examines the syntax of each Transact-SQL statement and returns any error messages without compiling or executing the statement.

Pranay Rana
+3  A: 

Use the following query

SET PARSEONLY ON
--Your query here
SET PARSEONLY OFF
rdkleine
+7  A: 

+1 to Eric's answer. But I've found SET FMTONLY ON to also be useful as SET NOEXEC ON doesn't appear to throw up all errors.

e.g.

SELECT * FROM ATableThatDoesNotExist

Running that with SET NOEXEC ON says it was successful, despite the table not existing in the database. Running it with SET FMTONLY ON instead, will throw the "Invalid object name" error.

SET FMTONLY ON also returns metadata about the resultset that would be returned, which can come in very handy

AdaTheDev
I get an error when using `SET NOEXEC ON` and `SELECT * FROM ATableThatDoesNotExist`
KM
@KM I don't get an error in either SQL2005 or SQL2008
Martin Smith
@KM - Same as Martin, I don't get an error either :/
AdaTheDev
@KM @Ada Apologies I didn't have the vital "GO" between my `SET NOEXEC ON` and the `SELECT `
Martin Smith
I didn't use a GO, I just ran the `SET NOEXEC ON` and got the `Command(s) completed successfully.` message and then ran the query, which then produced the error. If you run the `SET NOEXEC ON;SELECT...` you get no error. By butting a `GO` between the SRET and the SELECT it will give the error
KM
@KM - Aha. For me, on SQL Server 2008 RTM I *never* get the error. However, when I try on SQL Server 2005 it does behave as you say when you have the GO statement in. Where you trying on 2005? Seems odd the behaviour has changed
AdaTheDev
+5  A: 

Really it depends upon the purpose of the tests.

The most reliable way would be to use the rollback after every test if your statements lend themselves to that (aren't too heavy weight to make it viable).

I have done this in the past and have been glad to be notified of runtime issues that I wouldn't have caught any other way.

Martin Smith
+1 - I agree. Really executing the statement and doing a rollback after is going to be the most reliable way to test.
Eric Petroelje
+1: `SET NOEXEC ON` is only checking the query being valid. A query can be valid, but not return correct results.
OMG Ponies
+3  A: 

VSTSDBPro has a query parser you can access programmatically: http://blogs.msdn.com/b/gertd/archive/2008/08/21/getting-to-the-crown-jewels.aspx

Robert L Davis