Argument Exception in DeriveParameters method - sql

Dim id as integer = 1
Dim command as sqlcommand
Dim reader as idatareader
command = db.GetSqlStringCommand("select id, image, caption from profile where id = #id and image IS NOT NULL Order By NEWID()")
db.AddInParameter(command, "#id", DbType.Int32, id)
reader = db.ExecuteReader(Command)
The code is throwing an error I've never seen before....
SqlCommand.DeriveParameters failed because the SqlCommand.CommandText property value is an invalid multipart name "/port:4544 /path:"C:\sitepath" /vpath:"/sitepath"", incorrect usage of quotes.
How do I fix that error.

It looks like the code is failing at a deeper level than the code you have posted. I have received a similar error from within SQLServer Management Studio when I have not correctly defined the path to my DB.
How are you setting up the object 'db'?
What is your connection string? (Without password! :-))
The error is obviously related the badly formed string in terms of the quote positions. Do you know where entlib is constructing this string and how parts of it such as "C:\sitepath" are appearing with quotes as opposed to being appended as string literals?
I wonder if somewhere there is a declaration such as
Dim sRootPath As String = """C:\sitepath"""
..which is leading to the quotes being inserted into the constructed string.

I never saw this error, but perhaps this link helps: http://entlib.codeplex.com/Thread/View.aspx?ThreadId=60513
"What version of entlib is this? There's no overload in 4.1 for ExecuteReader that accepts an sql statement, there is one accepting a string but it should be the stored procedure name. Probably you are using this overload but I'm not sure since I'm getting a different error if I pass an sql statement"

I don't know about the error but the order by NEWID() bothers me a little. With newid() SQLServer calls the newid() function for each row in your dataset.

Related

ERROR [37000] [IBM][CLI Driver] CLI0118E Invalid SQL syntax. SQLSTATE=37000

I have a simple SQL statement query that is executed as command from C# code. It is targetting DB2. I created variables for the server/schemas as follows. It throws error.
private const string DB2Query
= #"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
I get this error.
ERROR [37000] [IBM][CLI Driver] CLI0118E Invalid SQL syntax. SQLSTATE=37000
However, I don't get that error when executing from SQL as follows:
SELECT Name as Name
FROM MyServer..FOR3.Application
WHERE ID = 'MOM'
To support this, I tried to also do something like below in code, still throws different error.
private const string DB2Query
= #"SELECT Name as Name FROM {ServerName}..{Schema}.Application WHERE ID = ?";
It throws error on this line of code:
DataApplicationBlockHelper<string>.Get(db, dbCommand, Obj);
UPDATE
I found the culprit. It's not replacing the {Schema} placeholder. When I actually removed that from query and placed the schema name, it worked like a charm. It's a .net thing I believe? Can someone please help how to replace {Schema} with a value fetched from web.config?
While I can't really speak to the syntax of DB2 queries themselves, so I'll rely on your assertion that the query itself should work...
What you have in C# is simply a string and nothing more:
private const string DB2Query = #"SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
Note that there's no need for the # operator in this string definition, so let's simplify:
private const string DB2Query = "SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
While this string appears intuitively to have a placeholder that can be replaced with a value, if there's no code which does that anywhere then it won't happen. For that you have a few options. For example, you can use a placeholder that string.Format() understands:
private const string DB2Query = "SELECT Name as Name FROM {0}.Application WHERE ID = ?";
And then later in a method somewhere, when you want to use that string, apply the format value to it:
var sql = string.Format(DB2Query, someVariable);
In this case someVariable (which doesn't even need to be a variable and could be a string literal) would be used to replace the placeholder in the string.
Or, if you want to keep the named placeholder, you can potentially replace it manually:
private const string DB2Query = "SELECT Name as Name FROM {Schema}.Application WHERE ID = ?";
and later in a method:
var sql = DB2Query.Replace("{Schema}", someVariable);
This would observably accomplish the same thing, perhaps with an extremely minor performance difference.
You could also take advantage of both approaches by using the more recent language feature of string interpolation. This would use the $ operator to apply format placeholders in place directly. I don't think you can use this in a const, it's more for a local variable. Something like this:
var sql = $"SELECT Name as Name FROM {someVariable}.Application WHERE ID = ?";
This would still perform the same replacement, putting someVariable where the placeholder is, it's just using a more concise syntax than a call to string.Format(). One thing to note about this syntax is that it makes it look more like this interpolation is happening directly in-place on the string. It's still a multi-step process behind the scenes, which is why it likely won't work on a const or on class members at all (and should I imagine produce a compiler error).
Remember that strings are immutable, so any operation you perform which modifies a string would be returning a new string rather than modifying the existing one in place.
In any case, you'll of course also need to apply your query parameter for the ? placeholder. Note that what C# considers to be a placeholder in a string formatting/interpolating operation and what DB2 considers to be a placeholder for a query parameter are two entirely different things which happen at different times in different environments. (One in the .NET runtime, one in the database server's query execution.) But again, I'm relying on your assertion that the database query itself works and the only problem we're focusing on here is the C# string placeholder.

LINQ to Entities does not recognize the method Int32 CompareString

I'm trying to execute the query below. However I'm getting the exception message:
LINQ to Entities does not recognize the method 'Int32 CompareString(System.String, System.String, Boolean)' method, and this method cannot be translated into a store expression.
I've narrowed it down to specifically the line "Where hearing.JudgeName = judge" but I see no reason why this would not be translated. JudgeName and judge are both strings and I'm connecting to a sql server. What is going on here?
Dim query = From hearing In Context.Hearings
From appeal In hearing.Appeals
From participation In appeal.Participations
Where Not appeal.SentDate.HasValue
Where appeal.StartDate <= pendingAsOfDate
Where hearing.JudgeName = judge
Even simplifying the query produces the same exception:
Dim query = From hearing In Context.Hearings
Where hearing.JudgeName = "Test"
Me.HasKey(Function(x) x.HearingId)
Me.Property(Function(x) x.HearingId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
Me.Property(Function(x) x.JudgeName).HasMaxLength(50)

Do I have to prefix sql parameter name with # sign when adding SqlParameters to the collection? [duplicate]

In one of our application the parameters passed to a stored procedure in this way
Dim parm As New SqlParameter("searchText", SqlDbType.VarChar)
parm.Direction = ParameterDirection.Input
parm.Size = 50
parm.Value="test"
cmd.Parameters.Add(parm)
and the procedure contains a parameter as #searchText
i.e. the parameter name passed from the code is searchText and that in the stored procedure is #searchText .
But it is working properly, I am always getting the required results.
So my question is like so there is no need to specify # before the parameter? Whether it will append #, can anyone please give an answer for this.
According to the documentation, the name must start with an #:
The ParameterName is specified in the form #paramname.
According to the source code (have a look at SqlCommand and SqlParameter.ParameterNameFixed in the reference source), an # is added automatically, if needed.
So yes, it works, but it's an undocumented feature. Best practice recommends that you do not rely on this and manually prefix your parameter name with an #.
Ref: SqlParameter.ParameterName Property and IDataParameter.ParameterName Property
The ParameterName is specified in the form #paramname. You must set ParameterName before executing a SqlCommand that relies on parameters. If you are using Sql Server as Database then you must specify # before
the parameter name.
your parameter name must be same as at backend eg. you have #searchText then in your parameter specification it must be SqlParameter("#searchText" ..
your code should be like this
Dim parm As New SqlParameter("#searchText", SqlDbType.VarChar)
parm.Direction = ParameterDirection.Input
parm.Size = 50
parm.Value="test"
cmd.Parameters.Add(parm)
Note: Oracle and SqLite use different use different character to specify parameter and there may be # symbol is not used specified by the specification of ado.net.
Edit: By comments
As you specified the link, it is also some sort of fix, but as per the msdn documentation, you must specify the positional parameter with '#' whether you are using any data provider oledb, sql, odbc. Ref
if (0 < parameterName.get_Length() && '#' != parameterName.get_Chars(0))
{
parameterName = "#" + parameterName;
}
Its not compulsory to specify the #. However, its a best practice.
Its similar in analogy to strings. There certainly is no harm in defining strings as such in .NET:
string s;
//Rest of the code follows;
But again, its a best practice to define them as :
string s = string.Empty;
You see, its a question of conventions and best practices!!!
I recommended you to use add "#" marker with your parameter name.
SqlParameter helps to add automatically, but others' parameter might not to.
Is the "#" symbol required? Yes and No. When you add a parameter using DbCommand, it's optional regardless of whether you're using SQL Server or not:
// Look Ma no # required!
DbCommand command = database.GetStoredProcCommand("StoredProctologistAndGambler");
database.AddInParameter(command, "Bet", DbType.Int32, fromLineNumber);
database.AddOutParameter(command, "Diagnosis", DbType.String, -1);
If you're going to reference the command later, however, the "#" prefix is required. Microsoft figured it was to hard to carry it over to the rest of the API.
var examResult = command.Parameters["#Diagnosis"]; // Ma! Microsoft lied! It requires the "#" prefix.

Is there a way to use default arguments that are the result of a function call in VB.NET?

I have a whole slew of database access functions which assume a particular connection string. Within my application I call
myList = DB_MyTable.GetTableItems()
and within GetTableItems() I have something like
Dim connection As SqlConnection = MyDB.GetConnection
So the connection string is in one place in the code, and I call a method to get it.
What I'm running into now is I want to reuse the same database functions, but with a different connection string. I can rewrite all of the functions like DB_MyTable.GetTableItems() easily because they're generated from a script, but within the main application code I'll need to take care of every function call that now needs to know what connection string I want to use.
I tried changing the arguments to GetTableItems() like this:
Public Shared Function GetTableItems(Optional ByVal useThisString as String = MyDB.GetConnection) As List(Of MyItems)
in hopes of being able to pass in, by default, the string I'm already using in most of the code, but I got an error saying that the default value had to be a constant expression. This would mean peppering a specific connection string everywhere, which I don't want to do.
Is there a way to accomplish what I'm after, or do I need to make the connection string a required argument and change all of the calls in my application to match the new signature?
Thanks as always!
Can you make your default value an empty string? Then, in your functions, if the useThisString variable is blank, then use default, else use the one you passed in? A littler dirtier, but just barely.

Strange Linq Error

I am using Linq to convert an array of any object to a CSV list:
String.Join(",", (From item In objectArray Select item.ToString()).ToArray())
This is giving me the strange error: "Range variable name cannot match the name of a member of the 'Object' class."
I can get round it by wrapping the string in a VB StrConv method, with a setting of "Nothing":
String.Join(",", (From item In oArray Select StrConv(item.ToString(), VbStrConv.None)).ToArray())
However, this seems like a bit of a hack and I would like to avoid it.
Does anyone have any ideas when this problems occurs, and any better ways to get round it?
Modify your code to:
String.Join(",", (From item In objectArray Select stringVal = item.ToString()).ToArray())
The problem is VB gives a name to the variable returned by Select clause. Implicitly, it tries to give the name ToString to item.ToString() which will clash with ToString method. To prevent so, you should explicitly specify a name (stringVal in above line).