2

Is there a way to get CommandText after replacing paramater values programmatically in .NET?

Assume we have a command:

let cmd = conn.CreateCommand()
cmd.CommandText <- "select * from smsqueue where smsqueueid=:pid"
cmd.CommandType <- CommandType.Text
cmd.Parameters.Add("pid", 0)

I want to get the prepared command text; which would be like this:

select * from smsqueue where smsqueueid=0

There are profilers to get this information, but I want to do this explicitly in code (e.g., F# or C#).

3 Answers 3

5

The replacement probably won't be performed in text - indeed it would be more hassle to do so. Why bother working out how to escape strings, represents dates in a particular text format etc when the driver can transmit them separately in a pre-planned binary format?

What goal are you trying to achieve? If this is for the purpose of logging, I would just log the command text and the parameters separately. Apart from being easier, that will make it clearer if you end up with a problem: you'll be able to tell whether the SQL was properly parameterized or not.

Sign up to request clarification or add additional context in comments.

7 Comments

This is totally rough! I use ExecuteCommand method of LINQ DataContext class to get a list of typed object (which I generate myself) and that (stupid?) method just gets string SQL; the problem is it does not replaces parameters if someone is using Oracle! [And I hate DataSet and Oracle has not LINQ and I did not found a good NHibernate code generator - besides that I work in such an environment that NHibernate, NLog, F#, ... are forbidden! SoI generate hand-written-like code >:( ]
@Kaveh: Is the problem that you're using named parameters but the driver only supports positional parameters? If you want to use LINQ with Oracle, you might want to look at the Entity Framework.
I think - as you and Joe Enos have stated - the problem is parameters never would be replaced before being sent. (And I will try not-named parameters - Thanks!)
With not named parameters, the problem is ExecuteCommand accepts just strings as values despite that the rest of parameters of the method (other than the 1st one) are of type Objects.
@Kaveh: I don't see what you mean. In particular, the docs of DataContext.ExecuteCommand show an example passing an integer...
|
2

Not possible, because that command is not being built. The program sends the exact command text you provided, including the parameter names, to the database engine, along with the parameter values separately. It never physically replaces them to come up with a new string.

If you really need something like that, you'll have to write your own string replacement function, but it would be misleading since that's not what really happens.

Comments

1

Code below needs to be added before command.execute so you get print of query which can be executed in SQL.

for (int x = 0; x < cmd.Parameters.Count; x++)
{    
if (cmd.Parameters[x].SqlDbType.ToString() == "VarChar" || cmd.Parameters[x].SqlDbType.ToString() == "Char")
    {
        Response.Write("<BR><BR>Declare " + cmd.Parameters[x].ToString() + " as " + cmd.Parameters[x].SqlDbType.ToString() + "(" + cmd.Parameters[x].Size + ")");
    }
    else
    {
        Response.Write("<BR><BR>Declare " + cmd.Parameters[x].ToString() + " as " + cmd.Parameters[x].SqlDbType.ToString());
    }

    Response.Write("<BR>SET " + cmd.Parameters[x].ToString() + " = '" + cmd.Parameters[x].SqlValue.ToString() + "'");
}
Response.Write("<BR>" + cmd.CommandText.ToString());

2 Comments

Please add some text to explain your code. Also, indent code by 4 spaces or using the {} button to improve the formatting.
Please add this to your answer, you can edit your post by clicking on the edit link below the post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.