I have an SQL where clause: -
where table1.resource in #ListOfRes
I'm trying to add to the SQL command like this:-
command.Parameters.AddWithValue("#ListOfRes", "'1','2'");
The result I'm looking for is: -
where table1.resource in ('1','2')
But I can't seem to build a string this way, is there a different data type I need to be using?
Nope, Not working. This is not how SQL works, regardless what you do.
IN (#variable) takes the content of the variable as ONE ELEMENT. There is no way to put multiple elements in it. Live with it. You need one variable for every element, or another approach (temp file, then using a join etc.)..
This simply is not a supported approach.
Related
I need to filter a sql request by passing a list of id to , this is the command:
var command = "select Software.Name as SoftwareName,SoftwareType.Name as SoftwareType from AssetManagement.Asset as Software inner join AssetManagement.AssetType as SoftwareType on (SoftwareType.Id = Software.TypeId) where Software.Id in (#P)";
cmd.Parameters.AddWithValue("#P", authorizedSoftwaresId);
authorizedSoftwaresId is a list of string , containing data like :
"7D23968B-9005-47A9-9C37-0573629EECF9,F1982165-3F6D-4F35-A6AB-05FA116BA279"
with that it returns to me just one row, I tried adding quotes foreach value but i got "converstion from string caractere to uniqueidentifier failed " exception
This is a pretty common problem and the answer might depend on your database engine and whether you're using ADO.Net, Dapper, etc.
I'll give you some hints from my own experience with this problem on both MS Sql Server and PostgreSQL.
A lot of people think AddWithValue is a devil. You might consider Add instead.
The IN (#P) in your SQL statement might be the source of your problem. Try the Any option instead. See Difference between IN and ANY operators in SQL ; I've had success with this change in similar situations.
If all of your inputs are GUIDs, you might consider changing the type to a collection of GUIDs, although I don't think this is the fix, you have to try everything when you're stuck.
If you have to, you can parse the string version of your collection and add the ticks (') around each value. This choice has consequences, like it may prevent you from using a parameter (#P), and instead construct the final SQL statement you desire (i.e., manually construct the entire WHERE clause through string manipulations and lose the parameter.)
Good luck.
I have a Visual Basic application where I have a connection to a MS SQL database. I have code which defines a SqlDataReader, opens the connection, and executes the ExecuteReader() command. I use the following code to retrieve the data from the reader
While myDataReader.Read()
Session("menu_PEO") = myDataReader("menu_PEO")
Session("menu_Transfer") = myDataReader("menu_Transfer")
Session("menu_Loan") = myDataReader("menu_loan")
End While
menu_PEO, menu_Transfer, and menu_loan are 3 of the column headings in the data that the SQL returns.
I am now tasked with converting the code to c#. I have the following code in c# which works:
while (dataReader.Read())
{
dbMenuPEO = dataReader.GetString(1);
dbMenuTransfer = dataReader.GetString(2);
dbMenuLoan = dataReader.GetString(3);
}
Since my SQL is a SELECT *, I can not guarantee the order of the data being returned so I dont want to rely on specifying the instance of the GetString.
Is there a way in c# to specify the column name that I would like to retrieve similar to the way it works in Visual Basic?
Thanks!
There are two ways to do this. The easy way is to use the named indexer:
dbMenuPEO = (string)dataReader["menu_PEO"];
Which is essentially the same as:
dbMenuPEO = (string)dataReader.GetValue(dataReader.GetOrdinal("menu_PEO"));
You can move the ordinal lookup outside of the loop, which is a bit more efficient. You can also use the the strongly-typed accessor which avoids the cast. This can be important when reading value types (int, dateTime, etc) as it avoid needing to box the value, which would happen with GetValue.
var menuPeoIdx = dataReader.GetOrdinal("menu_PEO");
while(dataReader.Read())
{
dbMenuPEO = dataReader.GetString(menuPeoIdx);
}
Generally, you should never use select * in a production system. Always explicitly list the columns you want. The reason is that it allows the underlying tables to change without having to fix the consuming code, or over-selecting columns that you don't need. Select * is a great tool for "exploring" a data set, but should only be used as a dev tool.
I have code which defines a SqlDataReader, opens the connection, and executes the ExecuteReader()
And isn't it the most incredibly tedious code to have to write? Many people have thought this over the time and many things have been invented to relieve you of the tedium of it. MarkPflug's answer directly addresses your question, but just in case you aren't aware that there are significant productivity boosts available I'd like to introduce you to one of these technologies
Is there a way in c# to specify the column name that I would like to retrieve similar to the way it works in Visual Basic?
Here's a way to do it, in that when you do this you don't have to type it. It avoids typing the same thing again that you've already typed (twice - once for the variable name, once in the SQL)
Use the nuget package manager built into visual studio, to install Dapper
Then lets say you have a class that holds your data:
//C#
record DbMenu(string DbMenuPEO, string DbMenuTransfer, string DbMenuLoan);
'or VB, if you like that sort of thing
Class DbMenu
Public Property DbMenuPEO as String
Public Property DbMenuTransfer As String
Public Property DbMenuLoan As String
End Class
You can get Dapper to make your query, add any parameters, open your connection, download your data, fill up a list full of your classes, close the connection and return it.. all in one line of code:
//C#
using var conn = ... //code here that gets a connection; doesn't need to be open
var myListOfDbMenus = conn.Query<DbMenu>("SELECT * FROM ... ");
'VB
Using conn = ...
Dim myListOfDbMenus = conn.Query(Of DbMenu)("SELECT * FROM ... ");
End Using
The short short version is: your c# class properties should be named the same as your columns. If they aren't, it's easiest to use AS xyz in the SQL to equalize the names. If you want to write a parameterized query, you provide #parameterNames that are the same as the property names of an anonymous object you pass at the same time as your query:
var q = conn.Query<Type>("SELECT ... WHERE col = #val1", new {val1 = "hello" } );
If you like writing SQL and having that low level control/don't want to use an ORM like EF, then Dapper lets you carry on doing the SQL directly as you're doing, but takes away all the repetitive surrounding boilerplate
The SQLDataReader class exposes a set of instance methods that allow to retrieve the value of a field of a specific type, such as GetInt32() and GetString(), which can be used in combination with the GetOrdinal() method
Example
dataReader.GetString(dataReader.GetOrdinal("YOUR FIELD NAME HERE"))
So, I have this lambda expression and it works just fine
list = list.Where(x => x.ListaDocumentoCaixa.Any(d => d.Observacao.Contains(term.Trim())));
I must add that this column is a varchar(6000) field. So far, this has been working just fine as I mentioned, but just recently I've ran into an issue. It seems that if the term of the search occurs from position 4001 of the string and on, the query fails to return anything to me.
After some debbuging I've found this commented on the query produced by Entity Framework
-- p__linq__0: 'maria stela gonsa' (Type = String, Size = 4000)
Then after some research I found this to be Entity's common behaviour, however, I can't have this kind of limitation on the application. My question is: Is there any way to change this behaviour ? I would like very much to avoid having to write this query as plain text and run this with ExecuteQuery if possible.
Thanks in advance for the help!
I would recommend you follow the following article, assuming you are using SQL server, about how to create a full text search index, and use it in Entity Framework with C#.
Running LIKE statements (which is what Contains() maps to) is HIGHLY inefficient on large varchar fields.
https://www.mikesdotnetting.com/article/298/implementing-sql-server-full-text-search-in-an-asp-net-mvc-web-application-with-entity-framework
EDIT: The summary of the link is:
1.) Create a full text index on the field using SQL server's wizard. That full text field will allow CONTAINS and FREETEXT searches on the whole field, and be much more efficient.
2.) Write a stored procedure that joins the table in question to results from the free text index.
3.) Make an Entity Framework class to represent results from that stored procedure, and use EF to call in and return a list of those results.
I have a winforms application which uses Linq to SQL. One of my database tables has a number of fields like this...
Area_1
Area_2
Area_3...
I need to be able to access these fields dynamically at runtime. I have a number of wired up buttons on my form which correspond to the different areas, so I created a string like this...
String sField = String.Format("Area_{0}", myAreaNumber);
And need to be able to read / write to the specific field using this variable. At this stage, I have already grabbed the entity object I need to work with. How can I go about using the 'sField' variable to read / write to a field?
You can run raw SQL directly on database using SqlQuery method on DbSet:
context.YourDbSet.SqlQuery("query string")
I have a list of msgs (it could be 24 or 100+).
I would need to remove many of these messages. I was wondering, what is the best way?
I dont like the idea of building names for 100+ elements and doing something like doRemove = Request["msgId" + i];
I prefer receive a array such as long[] and do something like
long[] removeThese = Request["remove"];
foreach ....
//DELETE msgId WHERE userId=#userId
However i dont know if creating an array and POSTing it is possible with HTML (and basic javascript?) or if its the best solution. How should i do this?
I would slap a <asp:CheckBoxList /> on there and when you need to submit changes, just take the .SelectedValue and pass it through into your SQL parameter (wherever that is done).
If you are on SQL 2008, you can take advantage of "Table-Valued Paramaters" (just google it) which you just pass any IEnumerable (pretty much any collection) in the variable and you can just JOIN to it in your UPDATE/DELETE/etc query.
Previous versions of SQL, the approach I use is very similar except just the string/VARCHAR is passed in to the query and you have to create a table variable or temp table to hold the values inserted from a split procedure. There are many ways to create the split procedure, but I've found the numbers-table approach works in all versions of SQL and has pretty good performance. See http://www.sommarskog.se/arrays-in-sql-2005.html for exhaustive reference of the possible performance implications of each approach.
Just say no to ' IN (' + #MyValuesCSV + ')'
:-)
You could create checkbox with same name
<input... name="mycheckbox" value="hello"></input>
<input... name="mycheckbox" value="world"></input>
On the server side, you could use Request("mycheckbox") & this should be an array of selected Items.
Alternatively, you could use asp.net checkboxlist.
link - http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.checkboxlist(VS.71).aspx
If you're looking for a "lightweight" solution, you could always have a hidden HTML variable and assign a javascript event to each checkbox that adds its index/id to the variable, creating a comma delimited list of Ids to process.
Then when the submit/confirm occurs, you can have your code behind page grab this string, convert it into a List/Array/Whatever that works best for your processing and finish things up.