This is a sample query:
declare #tempTable table
(
Id bigint
)
-- populating with temp Ids
select *
from TargetTable
where Id not in
(
select Id
from #tempTable
)
And this is C# code:
public DataTable Get(string sql)
{
var dataTable = new DataTable();
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand())
{
connection.Open();
command.Connection = connection;
command.CommandText = sql;
var dataReader = command.ExecuteReader();
dataTable.Load(dataReader);
}
return dataTable;
}
Running this code throws exception, complaining that:
Incorrect syntax near the keyword 'declare'.
Incorrect syntax near
')'.
I know it's possible to use join instead of #tempTable, but is there a way to run this query?
A SqlDataAdapter object can be used to populate a DataTable as follows. Instead of calling SqlCommand.ExecuteReader(), the SqlDataAdapter.Fill() method is used. In this example the argument to the Fill() method is the DataTable that will be populated. While this approach will work with the query you posted with the table variable, I'd strongly recommend converting this to a stored procedure and filling the DataTable from this instead. Additionally, unless the amount of data that's being sent into the table variable is very small using a temp table will offer more functionality (more accurate statistics, better DML performance, ROLLBACK participation, etc.) than table variables and I'd suggest using a temp table instead as well.
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataTable dataTable = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand command = new SqlCommand(cmd, connection);
da.SelectCommand = command;
connection.Open();
da.Fill(dataTable);
}
Stored Procedure Call:
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataTable dataTable = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
//use SP name for command text
SqlCommand command = new SqlCommand("usp_ProcedureName", connection);
//stored procedure command type
command.CommandType = CommandType.StoredProcedure;
da.SelectCommand = command;
connection.Open();
da.Fill(dataTable);
}
You can create a Stored Procedure of your query then add this to your code:
command.CommandType = CommandType.StoredProcedure;
Then use exec command
command.CommandText = "exec procedureName"
If your query location is in database itself.
Related
I'm trying to execute a query from OracleDataAdapter in C#, this query will go to a DBLink available in the DB, but for some reason when it needs to fill the datatable it throws me an error:
IndexOutOfRangeException - ndex was outside the bounds of the array
the code I'm trying to execute is:
OracleConnection conn = new OracleConnection(connectionString);
conn.Open();
DataSet dataSet = new DataSet();
OracleCommand cmd = new OracleCommand("select count(*) alive from dual#MYDBLINK");
cmd.CommandType = CommandType.Text;
cmd.Connection = conn;
using (OracleDataAdapter dataAdapter = new OracleDataAdapter())
{
dataAdapter.SelectCommand = cmd;
dataAdapter.Fill(dataSet); //Here is where it fails
}
The query works if I execute in sql developer, and the code works if I remove the DBLink information and let the query as select count(*) alive from dual, so I asume, that the issue here is something with the DBLink or the # character.
Using a SqlDataAdapter (or other ASP.NET technique), is it possible to make a single SQL call to both a stored procedure and run a select statement? Both have parameters.
I know you can combine multiple select statements...
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(myConnectionString))
{
connection.Open();
SqlDataAdapter cmd = new SqlDataAdapter("SELECT id FROM Table1 WHERE id=#myid; SELECT id FROM Table2", connection);
cmd.SelectCommand.Parameters.AddWithValue("#id",myid);
cmd.Fill(ds);
}
And you can call a stored procedure in a similar way...
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(myConnectionString))
{
connection.Open();
SqlDataAdapter cmd = new SqlDataAdapter("myStoredProcedure", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.SelectCommand.Parameters.AddWithValue("#id",myid);
cmd.Fill(ds);
}
But I'd like to combine the two into a single call.
I need to keep the stored procedure and select statements separate. I do not want to combine them into a single stored procedure.
Thanks for your help!
The trick is the exec function.
From the docs
It Executes a command string or character string within a Transact-SQL
batch, or one of the following modules: system stored procedure,
user-defined stored procedure, CLR stored procedure, scalar-valued
user-defined function, or extended stored procedure.
So you could do this:
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(myConnectionString))
{
connection.Open();
SqlDataAdapter cmd = new SqlDataAdapter("SELECT id FROM Table1 WHERE id=#myid; Exec myStoredProcedure #myid", connection);
cmd.SelectCommand.Parameters.AddWithValue("#myid",myid);
cmd.Fill(ds);
}
I am calling the following code in C# to fill a dataAdapter with a given stored procedure "sp1_name". The problem is that I want to call different stored procedures with different parameters. (All SP's do a SELECT)
Let's suppose that my stored procedure name is "SP_SOMESP", then everything works fine.
Let's suppose that my stored procedure name is "SP_SOMESP #Month= 10, #Year = 2010", then it doesn't work. It throws an exception that cannot find this stored procedure.
Any solutions?
Thanks!
//First Connection - SP1
using (SqlConnection con = new SqlConnection(conStr))
{
using (SqlCommand cmd = new SqlCommand(sp1_name, con)) //sp1_name = NAME + PARAMETERS
{
cmd.CommandTimeout = 3600;
cmd.CommandType = CommandType.StoredProcedure;
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd))
{
dataAdapter.Fill(results2);
}
}
}
First Issue:
Parameters in a stored procedure shouldn't be included along with its name
Second Issue:
Having a space in names of stored procedure isn't a good practice.
And for code behind
using(SqlConnection con = new SqlConnection("Your Connection String Here"))
{
SqlCommand cmd = new SqlCommand("sp_SomeName", con);
cmd.CommandType = CommandType.StoredProcedure;
//the 2 codes after this comment is where you assign value to the parameters you
//have on your stored procedure from SQL
cmd.Parameters.Add("#MONTH", SqlDbType.VarChar).Value = "someValue";
cmd.Parameters.Add("#YEAR", SqlDbType.VarChar).Value = "SomeYear";
SqlDataAdapter da = new SqlDataAdapter(cmd);
SqlDataSet ds = new SqlDataSet();
da.Fill(ds); //this is where you put values you get from the Select command to a
//dataset named ds, reason for this is for you to fetch the value from DB to code behind
foreach(DataRow dr in ds.Tables[0].Rows) // this is where you run through the dataset and get values you want from it.
{
someTextBox.Text = dr["Month"].ToString(); //you should probably know this code
}
}
You have to add in the parameters programmatically, see SqlCommand.Parameters.
It would be something like
cmd.Parameters.AddWithValue("#Month", 10);
cmd.Parameters.AddWithValue("#Year", 2010);
This would be after the command is declared and before it is executed.
If you find that you need to delcare the data type, then try it this way
cmd.Parameters.Add("#Month", SqlDbType.Int).Value = 10;
Check this,
using (SQLCommand cmd = new SQLCommand())
{
cmd.CommandText = "SP_SOMESP";
cmd.Parameters.Add("#Month", 10);
cmd.Parameters.Add("#Year", 2010);
cmd.CommandTimeout = 3600;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
}
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd))
{
dataAdapter.SelectCommand = cmd;
dataAdapter.Fill(results2);
}
I created the following stored procedure
CREATE PROCEDURE dbo.GetPoint
AS
SELECT point FROM tLocalGeo
Now I need execute that procedure from my C# Controller and save the data on a list.
As you can see the context of the problem is to get points so then I can display them on google map using javascript for that.
Can you give me some reference how to do it? Do I need SQLReader?
Thank you for your attention.
You can use SqlDataAdapter and DataSet and then can get values from dataset's first table.
SqlCommand cmd = new SqlCommand("store procedure Name", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter adapter= new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds);
if(ds.Tables[0]!=null && ds.Tables[0].Rows.Count > 0)
{
//your code
}
Hope it helps.
String strConnString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
SqlConnection con = new SqlConnection(strConnString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "GetPoint";
cmd.Parameters.AddWithValue("#EmployeeID", Empid) // ur input parameter//
cmd.Connection = con;
try
{
con.Open();
GridView1.EmptyDataText = "No Records Found";
GridView1.DataSource = cmd.ExecuteReader() ;
GridView1.DataBind();
}
Is it possible to call a stored procedure which will insert the details first and at the end will return a table. At present I have written two stored procedures for it: one for inserting and the other for getting the details. Now I'm trying to do both at the same time.
I'm using ExecuteScalar for inserting and ExecuteDataSet for selecting.
If your stored procedure returns data using a SELECT (of course, I suppose that you need to read that data) then you should use the SqlDataAdapter with its Fill method or an SqlDataReader using the ExecuteReader on the SqlCommand
ExecuteReader:
using(SqlConnection cn = new SqlConnection(...))
using(SqlCommand cmd = new SqlCommand(procName, cn))
{
cmd.CommandType = CommandType.StoredProcedure;
cn.Open()
using(SqlDataReader r = cmd.ExecuteReader())
{
while(r.Read())
{
// read every row and use the field values .....
}
}
}
SqlDataAdapter.Fill:
using(SqlConnection cn = new SqlConnection(...))
using(SqlCommand cmd = new SqlCommand(procName, cn))
{
cmd.CommandType = CommandType.StoredProcedure;
cn.Open()
using(SqlDataAdapter da = new SqlDataAdapter(cmd)
{
DataTable dt = new DataTable();
da.Fill(dt);
// DataTable filled with the data returned by the last SELECT in your SP
......
}
}
The SqlCommand.ExecuteReader or SqlDataAdapter.Fill will execute the stored procedure without looking at what the stored procedure does, but they expect that some kind of tabular data will be returned to loop over it
You write a procedure like this
CREATE PROCEDURE SP_Name
(
//PARAMETES
)
AS
BEGIN
//INSERT STATEMENT
//SELECT STATEMENT
END
and call ExecuteDataSet()
SqlConnection cn = new SqlConnectio(...)
SqlCommand cmd = new SqlCommand("procName", cn)
{
cmd.CommandType = CommandType.StoredProcedure;
cn.Open();
cmd.ExecuteScalar();
}