Difference between "?" and "#NAME" when specifying Parameter placeholders? - sql

If any, what is the difference between the following ways passing parameters.
SQLStr = "SELECT * FROM TABLE_NAME WHERE ID = ? "
command = new oleDbCommand(SQLStr, conn)
Command.Parameters.AddWithValue("#ID", Request.Querystring("ID"))
Vs.
SQLStr = "SELECT * FROM TABLE_NAME WHERE ID = #ID "
Command = new oleDbCommand(SQLStr, conn)
Command.Parameters.AddWithValue("#ID", Request.Querystring("ID"))
Maybe not in this example but could these two methods have different meanings? Perhaps when I need to pass the same value twice and I would be tempted to use the same variable name?
Thanks.

OleDbCommand does not support named parameters. Even if you use named parameter with # in your current query, their order will only matter. Currently you have only one parameter so you won't see the difference.
See: OleDbCommand.Parameters Property
The OLE DB .NET Provider does not support named parameters for passing
parameters to an SQL statement or a stored procedure called by an
OleDbCommand when CommandType is set to Text. In this case, the
question mark (?) placeholder must be used. For example:
SELECT * FROM Customers WHERE CustomerID = ?
Therefore, the order in which OleDbParameter objects are added to
the OleDbParameterCollection must directly correspond to the position
of the question mark placeholder for the parameter in the command
text.
Consider the following examples with multiple parameters:
SQLStr = "SELECT * FROM TABLE_NAME WHERE ID = #ID AND NAME = #Name";
Command = new oleDbCommand(SQLStr, conn);
Command.Parameters.AddWithValue("#Name", "ABC");
Command.Parameters.AddWithValue("#ID", Request.Querystring("ID")); //'A1'
Since #Name is added before #ID in the parameter collection, the query would look like :
SELECT * FROM TABLE_NAME WHERE ID = 'ABC' AND NAME = 'A1`; //assuming ID is A1
Note that ID got the value of NAME parameter and so as NAME got the value of ID, which is wrong.

Related

Execute sql command which return a declared sql table using EF

I have following SQL Query which I want to run using EF :
DECLARE #Users TABLE(Id INT, Name NVARCHAR(1000),Family NVARCHAR(1000));
INSERT INTO #Users
SELECT dbo.AspNetUsers.Id,dbo.AspNetUsers.FirstName,dbo.AspNetUsers.LASTNAME,
FROM dbo.AspNetUsers
Where dbo.AspNetUsers.ID IN
( SELECT users.ID FROM res.UserTag JOIN dbo.AspNetUsers users ON users.ID = UserTag.UserID WHERE TagID IN (8))
select * from #Users result
When I run it through this method :
dbcontext.DbSet().SqlQuery(query, "")
But it throws an error as below :
The data reader is incompatible with the specified 'Data.Models.AspNetUser'. A member of the type, 'Id', does not have a corresponding column in the data reader with the same name.
Actually, I want to cast the result to a another type (not defined in EF models), and I don`t want to use ASPNETUSER model, so I tried this:
if (_unitOfWork.Context().Database.Connection.State!=ConnectionState.Open)
_unitOfWork.Context().Database.Connection.Open();
DbCommand cmd = _unitOfWork.Context().Database.Connection.CreateCommand();
cmd.CommandText = procedureName;
cmd.CommandType = CommandType.Text;
using (var dr = cmd.ExecuteReader())
{
return dr;
}
But the datareadr (dr) has no records in this case.
Updated:
I found the solution. First of all, I have to put "Select ... " statement in the end of the query, also I can use custom type when calling db.Database.SqlQuery.
I found the solution. First of all, I have to put "Select ... " statement in the end of the query, also I can use custom type when calling db.Database.SqlQuery.

Error using SqlAdapter '{"Must declare the table variable \"#tableName\"."}'

I can't see where i'm going wrong and was wondering if you could help at all?
Just a basic SELECT with a table.
With regards to the error message, i thought i was declaring the #tableName variable in the parameters section?
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT * FROM #tableName",con);
adapter.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#tableName",
Value = tableName,
SqlDbType = SqlDbType.NVarChar
});
adapter.Fill(databaseList);
You cannot pass table names to SELECT as a parameter. Construct your SQL dynamically, by inserting the properly quoted (escaped) table name in the SQL string.
From clause not be expression so, cant send parameter
Try this
SqlDataAdapter adapter = new SqlDataAdapter(string.Format("Select * From {0}", "yourTableName"), con);

Passing array to a store procedure

I want to pass an array of 20k IDs to my stored procedure param in order to update a certain table.
Instead of running 20k update queries separately, I want to run 1 query to update all, it should improve my performances.
Any knows I can I pass a param to my stored proc?
I understood that NVARCHAR(MAX) is limited to 8000 chars, is it possible at all to send such a huge data using stored proc param?
Use a Table Value Parameter instead. See Use Table-Valued Parameters (Database Engine). A TVP is exactly as the name implies: a parameter that is a table. You assign to it from your client code a DataTable and the procedure (or you ad-hoc SQL codE) receives the entire DataTable as a parameter.This is an MSDN copied example:
// Assumes connection is an open SqlConnection.
using (connection)
{
// Create a DataTable with the modified rows.
DataTable addedCategories = CategoriesDataTable.GetChanges(
DataRowState.Added);
// Define the INSERT-SELECT statement.
string sqlInsert =
"INSERT INTO dbo.Categories (CategoryID, CategoryName)"
+ " SELECT nc.CategoryID, nc.CategoryName"
+ " FROM #tvpNewCategories AS nc;"
// Configure the command and parameter.
SqlCommand insertCommand = new SqlCommand(
sqlInsert, connection);
SqlParameter tvpParam = insertCommand.Parameters.AddWithValue(
"#tvpNewCategories", addedCategories);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.CategoryTableType";
// Execute the command.
insertCommand.ExecuteNonQuery();
}

What's the best way to update a List on the database?

If I have the following list in C# that was loaded from the database
List<User> user = GetUsers(foo);
and it was updated and I want to store those changes in the database what's the best way of doing it using SQL? It should insert the records added to that list, updated the modified records and delete the ones that are not present in the collection.
I'm no using the EntityFramework so I need to do this using SQL.
Copy this list to datatable and set datatable RowStat as (modified,deleted,new)
and update datatable using sqldataadapter
Here's an example that adds or inserts a row. It searches for a row with a specific UserID. If the row exists, it uses update to grant the user a point. If the row does not exist, a new row is created with insert.
var connectionString = "Data Source=myServerAddress;" +
"Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;"
using (var con = new SqlConnection(connectionString))
{
con.Open();
var com = con.CreateCommand();
com.Parameters.AddWithValue("#UserId", userId);
com.CommandText = #"
if exists (select * from YourTable where UserId = #UserId)
update YourTable set TrollPoints = TrollPoints + 1 where UserId = #UserId
else
insert YourTable (UserId, TrollPoints) values (#UserId, 1)
";
com.ExecuteNonQuery();
}
The use of parameters allows the server to chache the execution plan, and also helps against SQL injection.

Conditional Where Clause in SQL Query

I have developing the MVC application for generating the report. I have provided many search option like below
Customer id
Customer name
Customer E-mail
State
Country
User 1:
If the some user will give inputs to only some Values like
Customer id = 1
Customer name = A
By default other parameters are passed as null to the stored procedure.
Customer E-mail
State
Country
User 2:
If the some user will give inputs to only some values like
Customer E-mail=xtz#gmail.com
By default other parameters are passed as null to the stored procedure.
Customer id
Customer name
State
Country
How can i use the where clause in the SQL query in the stored procedure. Can we do it like below
string qry = select * from table_name where status != d
if (#customerID!=null)
qry = qry + "and customer_id=#customerID"
if (#customerName!=null)
qry = qry + "and customer_name=#customerName"
Please let me the best approach on this.
Thanks,
Velu
If you are creating dynamic SQL then you can do just like you are above:
DECLARE #SQL NVARCHAR(MAX)
SELECT #SQL = 'SELECT * FROM TABLE '
if (#customerID IS NOT NULL)
SQL = SQL + " AND customer_id = #customerID"
Or another option is to handle it like
SELECT *
FROM TABLE
WHERE (#customerID IS NULL OR customer_id = #customerID)
I prefer the second as it is utilizing parametrized variable. First example needs to take into consideration malicious input far more intensely.
You could do dynamic SQL, but a simpler method is:
WHERE (ISNULL(#param1,1) = 1 OR [col1] = #param1)
AND (ISNULL(#param2,1) = 1 OR [col2] = #param2)
AND ...
you'll have to pass all the variables as parameters into the SP and then do your logic in there.
SqlCommand cmd = new SqlCommand("STORED_PROC_NAME", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#CustomerID", custId));
var rdr = cmd.ExecuteReader();