This question already has answers here:
How to pass an array into a SQL Server stored procedure
(13 answers)
Closed 8 years ago.
I have a list List<Int32> containing ids and want to select some values from another table where id=ids[0],ids[1],...
it look like this:
string query=String.Format("# SELECT values from Table WHERE id=???");
How to get result?
P.S. as i listen- that this way is not right.
So, another way to do that- use Join:
string queryString = String.Format(#" SELECT * FROM Table1 [t1]
join [Table2] [t2]
on [t1].idTable1=[t2].id where [idParamValue]={0}", idParamValue);
So, then i should use :
using (var sqlCmd = new SqlCommand(queryString, _connection))
{
using (var sqlReader = sqlCmd.ExecuteReader())
{
while (sqlReader.Read())
{
var param1=(String)sqlReader["param_name"];
}
}
}
Thank you!
SELECT * FROM Table WHERE id IN (79,86,42)
You can use below query :-
string query=String.Format("# SELECT values from Table WHERE id in(value1,value2,value3,value4,...)");
Related
This question already has answers here:
Adding multiple parameterized variables to a database in c#
(2 answers)
Parameterize an SQL IN clause
(41 answers)
Closed 7 days ago.
I am trying to pass array of parameter to SQL query as a parameterized query.
SELECT D.PATIENTID AS PATIENTID,
D.FNAME AS FIRSTTNAME
FROM DETAILS D INNER JOIN PATEINT P ON P.PATIENTID=D.PATIENTID
WHERE P.COURSENAME IN ('PA-PA','PA-RO','RO-PA') AND D.STARTDATE BETWEEN '20241201' AND '20241231'
So above query I want to pass as
SELECT D.PATIENTID AS PATIENTID,
D.FNAME AS FIRSTTNAME
FROM DETAILS D INNER JOIN PATEINT P ON P.PATIENTID=D.PATIENTID
WHERE P.COURSENAME IN (#param1,#param2,#param3) AND D.STARTDATE BETWEEN #AntiParam1 AND #AnitParam2
(#param1,#param2,#param3) will be #AnitParam3
Tried below method:
List<SqlParameter> params = new List<SqlParameter>();
foreach (var o in strPackageCode)
{
SqlParameter paramRef = new SqlParameter();
paramRef.ParameterName = "#Param" + params.Count;
paramRef.Value = o;
params.Add(paramRef);
}
And called ExecuteDataSet(Query, parameters); but it takes #AnitParam2 as 'System.Collections.Generic.List`1[System.Data.SqlClient.SqlParameter]'
#AnitParam0=N'20241201',#AnitParam1=N'20241231',#AnitParam2=N'System.Collections.Generic.List`1[System.Data.SqlClient.SqlParameter]'
This question already has answers here:
How to replace text in string in C#?
(2 answers)
Closed 8 years ago.
SELECT TOP 100 * FROM DSMS_Log.dbo.LoggingDetail WITH(NOLOCK) ORDER BY LogTime DESC
I want to replace find 'TOP 100' string and replace it with 'TOP 200' or any other value.
Can you please let me know how to do it in C#?
if you are writing query in your c# code you can use:
int topCount=1000;
string query= "SELECT TOP ("+i.toString()+") * FROM DSMS_Log.dbo.LoggingDetail WITH(NOLOCK) ORDER BY LogTime DESC"
But if you want to send parameter to your SP then you can use:
Declare #i int=1000;
SELECT TOP (#i) * FROM DSMS_Log.dbo.LoggingDetail WITH(NOLOCK) ORDER BY LogTime DESC
It sounds to me as if you simply want to replace part of the string with another, so like:
string sql = "SELECT TOP 100 * FROM DSMS_Log.dbo.LoggingDetail WITH(NOLOCK) ORDER BY LogTime DESC";
sql = sql.Replace("TOP 100", "TOP 200");
If the number is dynamic and you want to replace it with a different one you could use regex:
string sql = "SELECT TOP 100 * FROM DSMS_Log.dbo.LoggingDetail WITH(NOLOCK) ORDER BY LogTime DESC";
string pattern = #"\bTOP\b *(\d+)";
sql = Regex.Replace(sql, pattern, m => "TOP 200");
DECLARE #topval int=100
SELECT TOP #topval * FROM DSMS_Log.dbo.LoggingDetail WITH(NOLOCK) ORDER BY LogTime DESC
you want to use string replace function.string replace function
If you are not using stored procedures, you can concatenate the limit in the command text in C#:
int toplimit = 200;
cmd.CommandText="SELECT TOP " + toplimit.ToString() + " * FROM DSMS_Log.dbo.LoggingDetail WITH(NOLOCK) ORDER BY LogTime DESC";
I think it should be as simple as this
private string GetSql(int maxRecords)
{
string statement = "SELECT TOP " + maxRecords + " FROM DSMS_Log.dbo.LoggingDetail WITH(NOLOCK) ORDER BY LogTime DESC ";
return statement;
}
you can also modify the parameters and change your SQL query.
I'd use regex for that. Because i think its the best way to get all variations in one statement.
string oldString = "Select top 500 from wherever";
string newLimit = "top 20";
string result = System.Text.RegularExpressions.Regex.Replace(oldString , "TOP (\\d)+",newLimit , System.Text.RegularExpressions.RegexOptions.IgnoreCase );
So put in your old string, replace any "TOP x" string with another version given as newLimit in my Example.
For C# solution you will do better using a parameter instead of string manipulation.
simply like this:
int count = 200;
var sql = string.Format("SELECT TOP {0} FROM [Rest_Of_Your_Query]", count);
if you will use a parameter it will be easier for you to know when to change (in case you want to replace only when the value is 100) and to which value (200, 300 whatever).
For SQL solution take a look at the answer from #Ganesh_Devlekar
This question already has an answer here:
SQL "WHERE IN" query conversion to LINQ
(1 answer)
Closed 8 years ago.
I am trying to query the db with an IN clause using EF:
List<int> ids = new List<int> {1,2,3,4....20};
string sql = GetSql(ids);
//sql is "SELECT * FROM Student WHERE Id in (#p0, #p1, #p2 ... #p19)"
var res = db.Set<Student>().SqlQuery(sql, ids);
But I get the following exception :
No mapping exists from object type System.Collections.Generic.List`1[[System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] to a known managed provider native type.
I am handling in clause like this:
List<int> ids = new List<int> {1,2,3};
db.Set<Student>().Where(r => ids.Contains(r.ID));
UPDATE:
You do as follows (I have not tested by myself but it should do your job)
public List<CustomObject> ExecuteCustomQuery(List<int> items)
{
var ids = string.Join(",", items.Select(i => i.ToString()).ToArray());
string query = "SELECT Column1, Column1 FROM TABLE1 where id in (" + ids + ")";
return dbContext.Database.SqlQuery<CustomObject>(query).ToList();
}
CustomObject has got two properties of returning columns of select statement.
Let me know how did you go.
thanks.
I am passing ids list as a varchar(500) and based upon that ids records are required.My sql code is
declare #Ids varchar(500) = '12964,12965,12966'
select *
from tblBooks
where BookID in (#Ids)
where BookID is varchar(50).Number of Ids can be 100.Converting #Ids into int gives following error
Conversion failed when converting the varchar value
'12964,12965,12966' to data type int
How do i find result as #Id are not converted into Int.
Use a table variable:
DECLARE #Ids TABLE (ID INT);
INSERT #Ids VALUES (12964),(12965),(12966);
SELECT *
FROM tblBooks
WHERE BookID in (SELECT ID FROM #Ids);
If you need to pass this to a procedure then you can use a table valued parameter:
CREATE TYPE dbo.ListOfInt AS TABLE (ID INT);
GO
CREATE PROCEDURE dbo.GetBooks #IDs dbo.ListOfInt READONLY
AS
BEGIN
SELECT *
FROM tblBooks
WHERE BookID in (SELECT ID FROM #Ids);
END
GO
DECLARE #IDs dbo.ListofInt;
INSERT #Ids VALUES (12964),(12965),(12966);
EXECUTE dbo.GetBooks #Ids;
Or From c#
var table = new DataTable();
table.Columns.Add("ID", typeof(int));
// ADD YOUR LIST TO THE TABLE
using (var connection = new SqlConnection("Connection String"))
using (var command = new SqlCommand("dbo.GetBooks", connection))
{
command.CommandType = CommandType.StoredProcedure;
var param = new SqlParameter("#Ids", SqlDbType.Structured);
param.TypeName = "dbo.ListofInt";
param.Value = table;
command.Parameters.Add(table);
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
// do something
}
}
}
Once the TYPE is in place, you don't even need to use a stored procedure. You can simply call a normal query:
using (var connection = new SqlConnection("Connection String"))
using (var command = new SqlCommand("SELECT * FROM tblBooks WHERE BookID IN (SELECT ID FROM #IDs)", connection))
{
var param = new SqlParameter("#Ids", SqlDbType.Structured);
param.TypeName = "dbo.ListofInt";
param.Value = table;
command.Parameters.Add(table);
connection.Open();
// ETC
}
Doing the split in c# using String.Split() and passing the list to SQL will be more efficient than any approach that does the split in SQL
You can write the query as this:
declare #Ids varchar(500) = '12964,12965,12966'
select *
from tblBooks
where ','+cast(BookID as varchar(500))+',' like '%,'+#Ids+',%';
But you don't want to do that because the performance is bad -- the query cannot use indexes.
Three other options. Use dynamic SQL and plug the list directly into the query. Or use a split function to split the string. Or use a table variable:
declare #ids table (id int);
insert into #ids(id)
select 12964 union all select 12965 union all select 12966;
select b.*
from tblBooks b
where b.BookId in (select id from #ids);
This won't work. SQL Server does not split strings for you implicitly and there is no built in string split function in SQL Server either.
If you are driving this via C# you can use Table value parameters. You can also pass your query through Dapper-Dot-Net which will automatically parameterize an "In" query.
If you really must do this in T-SQL, you can also use a string splitting logic here is a relatively concise one.
SELECT i.value('./text()[1]', 'int') [id] into #ids
FROM( values(CONVERT(xml,'<r>' + REPLACE(#Ids+left(##dbts,0),',','</r><r>') + '</r>')) ) a(_)
CROSS APPLY _.nodes('./r') x(i)
select *
from tblBooks a
join #ids i on i.id = a.bookId
Create this function:
CREATE FUNCTION [dbo].[SplitDelimiterString] (#StringWithDelimiter VARCHAR(8000), #Delimiter VARCHAR(8))
RETURNS #ItemTable TABLE (Item VARCHAR(8000))
AS
BEGIN
DECLARE #StartingPosition INT;
DECLARE #ItemInString VARCHAR(8000);
SELECT #StartingPosition = 1;
--Return if string is null or empty
IF LEN(#StringWithDelimiter) = 0 OR #StringWithDelimiter IS NULL RETURN;
WHILE #StartingPosition > 0
BEGIN
--Get starting index of delimiter .. If string
--doesn't contain any delimiter than it will returl 0
SET #StartingPosition = CHARINDEX(#Delimiter,#StringWithDelimiter);
--Get item from string
IF #StartingPosition > 0
SET #ItemInString = SUBSTRING(#StringWithDelimiter,0,#StartingPosition)
ELSE
SET #ItemInString = #StringWithDelimiter;
--If item isn't empty than add to return table
IF( LEN(#ItemInString) > 0)
INSERT INTO #ItemTable(Item) VALUES (#ItemInString);
--Remove inserted item from string
SET #StringWithDelimiter = SUBSTRING(#StringWithDelimiter,#StartingPosition +
LEN(#Delimiter),LEN(#StringWithDelimiter) - #StartingPosition)
--Break loop if string is empty
IF LEN(#StringWithDelimiter) = 0 BREAK;
END
RETURN
END
Then call it like this:
declare #Ids varchar(500) = '12964,12965,12966'
select *
from tblBooks
where BookID in (SELECT * FROM dbo.SplitDelimiterString(#ids,','))
one way is to cast int to varchar. many other ways....
select *
from tblBooks
where CAST(BookID as varchar(50)) in (#Ids)
related: Define variable to use with IN operator (T-SQL)
I am using a C# console app to get some data from a MySql database and I have some problems getting a query right
As it is now:
SELECT * FROM Customer
WHERE EXISTS ( SELECT * FROM Customer_x_Billing c WHERE Customer.`customer id` = c.customer_id)
AND 2011 -04 -03 < ( SELECT last_changed FROM Customer_x_Billing c WHERE Customer.`customer id` = c.customer_id )
ORDER BY Customer.`customer id`
How can I improve this one?
I want to get all customers that has their ID in both Customer and Customer_x_Billing table and where the last_changed date in Customer_x_Billing is greater than a parameter (2011-04-03 in this case). If I set the date to 2012-04-03 it shouldn't return any row but it returns all records that match the first condition (exist in both).
Try below one
SELECT * FROM Customer
INNER JOIN
Customer_x_Billing ON Customer.`customer id` = Customer.customer_id
WHERE last_changed > 2011 -04 -03
ORDER BY Customer.`customer id`
problem with you query is you are scanning Customer_x_Billing table two time which is not needed, its better to go for one inner join which will stisfy you first condition the exists one and second satisfy by writing the where clause.
SELECT c.* FROM Customer c INNER JOIN Customer_x_Billing cb ON cb.customer_id = c.id WHERE DATE(cb.last_changed) > '2011-04-03' ORDER BY c.id;
If I read your question right I belive you can achieve this with an INNER JOIN...
SELECT *
FROM Customer c
INNER JOIN Customer_x_Billing b
ON c.customer_id = b.customer_id
WHERE last_changed_date > '2011-04-03'
SELECT Customer.* FROM Customer c INNER JOIN Customer_x_Billing b
ON c.`customer id`=b.`customer id`
WHERE last_changed>'2011-04-03'
ORDER BY c.`customer id`
Anyway beware of dates in your query...
More or less like this.
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText
= "SELECT * FROM Custromer c JOIN Customer_x_Billing cb ON c.'customer id' = cd.'customer id' Where last_change < #lastChangeDate";
cmd.Parameters.AddWithValue("#lastChangeDate", new DateTime(2011,04,03));
using (SqlDataReader drd = cmd.ExecuteReader())
{
while (drd.Read())
{
// Read from data reader
}
}
}
}
For sake of your application you should get familiar with some database tutorial, and try to understand the concept of relational databases.