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

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);

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.

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

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.

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();
}

stored procedure inserts truncated value

I have a stored procedure that uses several input parameters and insert them into Sql Database. There is a problem with one parameter, #CustomerId, that is truncated (but not always) when inserted into database.
C#:
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CustomerId", Convert.ToInt32(customerId));
cmd.Connection = sqlConn;
sqlConn.Open();
cmd.ExecuteNonQuery();
sqlConn.Close();
Sql SP:
#CustomerId int
INSERT INTO dbo.tblOffers
(CustomerId)
VALUES
(#CustomerId)
sql table datatype:
CustomerId int not null
Example: 564276117 truncated to 4276117 (but its not happening all the time, and there are values greater than 560000000 that are inserted properly)
What am I doing wrong? Thanks
Try Parameters.Add() method instead of AddWithValue.
cmd.Parameters.Add("#CustomerId",SqlDbType.Int).Value=CustomerID;
Would you please try as below: using ToInt64
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CustomerId", Convert.ToInt64(customerId));
cmd.Connection = sqlConn;
sqlConn.Open();
cmd.ExecuteNonQuery();
sqlConn.Close();

How to retrieve scalar value from stored procedure (ADO.NET)

If in the stored procedure, I just execute one statement, select count(*) from sometable, then from client side (I am using C# ADO.Net SqlCommand to invoke the stored procedure), how could I retrieve the count(*) value? I am using SQL Server 2008.
I am confused because count(*) is not used as a return value parameter of stored procedure.
thanks in advance,
George
Either you use ExecuteScalar as Andrew suggested - or you'll have to change your code a little bit:
CREATE PROCEDURE dbo.CountRowsInTable(#RowCount INT OUTPUT)
AS BEGIN
SELECT
#RowCount = COUNT(*)
FROM
SomeTable
END
and then use this ADO.NET call to retrieve the value:
using(SqlCommand cmdGetCount = new SqlCommand("dbo.CountRowsInTable", sqlConnection))
{
cmdGetCount.CommandType = CommandType.StoredProcedure;
cmdGetCount.Parameters.Add("#RowCount", SqlDbType.Int).Direction = ParameterDirection.Output;
sqlConnection.Open();
cmdGetCount.ExecuteNonQuery();
int rowCount = Convert.ToInt32(cmdGetCount.Parameters["#RowCount"].Value);
sqlConnection.Close();
}
Marc
PS: but in this concrete example, I guess the alternative with just executing ExecuteScalar is simpler and easier to understand. This method might work OK, if you need to return more than a single value (e.g. counts from several tables or such).
When you execute the query call ExecuteScalar - this will return the result.
Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored.
Since you are only returning one value this would return just the value from your count expression. You will need to cast the result of this method to an int.
marc_s answer worked fine for integer. but for varchar the lenght must be specifed.
cmdGetCount.Parameters.Add("#RowCount", SqlDbType.varchar,30).Direction = ParameterDirection.Output;