Passing DataSet to Stored Procedure - c#

I have the following Stored Procedure that receives a DataSet as parameter and Inserts into table Excel.
CREATE PROCEDURE spInsertInvoice
#tblInvoice InvoiceType READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Excel
SELECT Template, Cust_Name, Invoice_No,InvoiceDate FROM #tblInvoice
END
In my code file I am trying to read the Excel Sheet and filling the dataset. But problem is I am a bit confused as to how should I send the DataSet as Parameter to the stored Procedure.
This is what I have tried so far, but it doesn't seem to work
if (FileUpload1.HasFile)
{
string path = string.Concat((Server.MapPath("~/temp/" + FileUpload1.FileName)));
FileUpload1.PostedFile.SaveAs(path);
OleDbConnection oleCon = new OleDbConnection("Provider=Microsoft.Ace.OLEDB.12.0;Data Source=" + path + ";Extended Properties = Excel 12.0;");
OleDbCommand Olecmd = new OleDbCommand("select * from [Sheet1$]", oleCon);
OleDbDataAdapter dtap = new OleDbDataAdapter(Olecmd);
DataSet ds = new DataSet();
dtap.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
if (ds.Tables[0].Rows.Count > 0)
{
string consString = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(consString))
{
using (SqlCommand cmd = new SqlCommand("spInsertInvoice"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
cmd.Parameters.AddWithValue("#tblInvoice", ds);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
When I execute it, it throws ArgumentException on cmd.ExecuteNonQuery()
No mapping exists from object type System.Data.DataSet to a known
managed provider native type.

You cannot pass dataset to stored procedure but you can pass datatable to stored procedure. Follow below algorithm to execute it:
1) Create Table type in sql server for the DataTable which you want to pass.
2) Declare input variable for given table type as readonly in stored procedure.
3) Pass that data table to procedure.
This only restricts your table type parameter sequence and datatable column sequence should be same.
You can refer this link Sending a DataTable to a Stored Procedure
Or Table-Valued Parameters

You can't parameterize your table name, basically.
Parameterized SQL is just for values - not table names, column names, or any other database objects. This is one place where you do probably want to build the SQL dynamically - but with a white-listed set of options or strong validation before you put this table name in your sql query.
It that line;
cmd.Parameters.AddWithValue("#tblInvoice", ds);
You try to pass your DataSet to your table name which does not make sense.

Related

Using an SqlDataAdapter with a stored procedure and parameters to update as well as retrieve values

In How to use a DataAdapter with stored procedure and parameter, the data adapter's selectCommand property has been used. Can the same be used if a stored procedure updates as well as retrieves data from a database?
On implementing it, and using the selectCommand (and not the property, it seems to work alright.
...
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlQuery, sqlConnection);
foreach (SqlParameter sqlParameter in sqlParameterCollection)
{
sqlCommand.Parameters.Add(new SqlParameter(sqlParameter.ParameterName, sqlParameter.Value));
}
sqlDataAdapter.SelectCommand = sqlCommand;
DataSet dataSet = new DataSet();
sqlDataAdapter.Fill(dataSet);
...
The short answer is yes. Passing parameters to a stored procedure which updates and returns values is no different from the SqlDataAdapter side compared to a stored procedure that only returns values based on parameters passed in.

SQLiteDataAdapter converts empty value to 0 - how to prevent that?

Below is a snippet of the code. As you can see, that method returns a table from SQLite database, and adds that table to a DataSet if it doesn't exist yet.
SQLiteConnection connection;
DataSet Set = new DataSet();
DataTable GetTable(string tableName, string command)
{
if (!Set.Tables.Contains(tableName))
{
var adapter = new SQLiteDataAdapter(command, connection);
SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adapter);
adapter.FillSchema(Set, SchemaType.Source, tableName);
adapter.Fill(Set, tableName);
adapter.Dispose();
}
return Set.Tables[tableName];
}
To call it, for example
DataTable myTable = GetTable("MyTable", "select * from MyTable);
To access a field:
object emptyValue = myTable.Rows[0]["Some_Column"];
There are some cells in the SQLite file that are of type INT, and their values are empty (not null). However when I'm trying to populate myTable, they are conveniently converted to 0's which I DO NOT WANT. How do I go about fixing that? I would like to keep empty values (and null values) as null's when importing to C#.
You can retrieve the row I was talking about above by executing the following SQL statement:
select * from MyTable where some_column = ''
The SQLite file that I use is SQLite3. Just in case it helps.
Thanks in advance!

DataSet call insert, update and delete stored procedures

Through designer I have created a typed data set and included stored procedures for insert / update / delete. The problem is now, how to call those stored procedures? How to actually change data in database this way? And how to receive answer from db (number of rows changed)?
try this for get data from database.
DataSet ds = new DataSet("dstblName");
using(SqlConnection conn = new SqlConnection("ConnectionString"))
{
SqlCommand sqlComm = new SqlCommand("spselect", conn);
sqlComm.Parameters.AddWithValue("#parameter1", parameter1value);
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = sqlComm;
da.Fill(ds);
}
Similarly you need to call "spdelte" etc.
I found out that far easiest way is through designer - create table adapter and simply set it to call stored procedure. No extra typing needed, arguments are also added to procedure call.

Access results of SQL Server stored functions in C#

I have created a few stored functions in SQL Server that return a table via a select statement. Like so:
CREATE FUNCTION [dbo].[mFunSelectStudents] ()
RETURNS #result TABLE
(IDStudent int,
Name nchar(50),
Password nchar(50))
AS
BEGIN
INSERT INTO #result select * from School.dbo.Student
RETURN
END
I tried to assign the function to an SqlDataAdapter in c# like this:
SqlCommand cmd = new SqlCommand("mFunSelectStudents", con);
SqlDataAdapter adpStudents = new SqlDataAdapter();
adpStudents.SelectCommand = cmd;
But this doesn't work..
Where #result is a return parameter of the stored function. Now, how do I call the function in C# and assign the data to a grid ?
Any help is appreciated..
The command cannot be just the name of the function. You are supposed to put a SQL command there, and in SQL one retrieves data from a TVF by SELECTing from it, like this:
SELECT * FROM dbo.mFunSelectStudents()
Consequently, the first line of your C# code snippet should be:
SqlCommand cmd = new SqlCommand("SELECT * FROM dbo.mFunSelectStudents()", con);
Wrap the function in a stored procedure, or do the work itself in a SP. The results of a single select statement will be accessible as a DataTable in the C# client.
create proc selectSomeData
.
.
.
In the client, your commandType would be StoredProcedure and the CommandText would be the name of the sp.
Your first line :
SqlCommand cmd = new SqlCommand("mFunSelectStudents", con);
Is correct, however this one you should check it
SqlDataAdapter adpStudents.SelectCommand = cmd;
First you need to use new with the SqlDataAdapter before you can assign the selectCommand, as follows:
SqlDataAdapter adpStudents = new SqlDataAdapter(cmd);
Assign the command to the DataAdapter
adpStudents.SelectCommand = cmd;
And then you prepare a Dataset
DataSet ds = new DataSet();
Fill it with your DataAdapter
adpStudents.Fill(ds);
Assign it to your grid
gridName.DataSource = ds;
And call DataBind to update the info on the grid
gridName.DataBind();

Schema from stored procedure

I have a procedure, I want to read schema of the procedure. To retrieve view schema I use the query shown here. Same way I want to get schema of stored procedure. How to get it? Plz show some syntax.
public static DataTable SchemaReader(string tableName)
{
string sql = string.Format("Select * from {0}", tableName);
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
SqlDataReader reader = cmd.ExecuteReader();
DataTable schema = reader.GetSchemaTable();
reader.Close();
conn.Close();
return schema;
}
If have any query plz ask.Thanks in advance.
you could do
public static DataTable SchemaReader(string tableName)
{
string sql = "MySP";//replace this with your store procedure name
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader reader = cmd.ExecuteReader();
DataTable schema = reader.GetSchemaTable();
reader.Close();
conn.Close();
return schema;
}
Hope this help
This is an answer that does not call the SP - if you do, you may inadvertently affect data:
SELECT * FROM sys.dm_exec_describe_first_result_set ('owner.sprocName', NULL, 0) ;
This returns the result set :
is_hidden
column_ordinal
name
is_nullable
system_type_id
system_type_name
max_length
precision
scale
collation_name
user_type_id
user_type_database
user_type_schema
user_type_name
assembly_qualified_type_name
xml_collection_id
xml_collection_database
xml_collection_schema
xml_collection_name
is_xml_document
is_case_sensitive
is_fixed_length_clr_type
source_server
source_database
source_schema
source_table
source_column
is_identity_column
is_part_of_unique_key
is_updateable
is_computed_column
is_sparse_column_set
ordinal_in_order_by_list
order_by_is_descending
order_by_list_length
error_number
error_severity
error_state
error_message
error_type
error_type_desc
You could get information about a stored procedure's parameters but, without executing it, SQL Server cannot tell you the structure of the dataset(s) returned by the stored procedure. Since executing a stored procedure can have side effects, ADO.NET doesn't provide a method for telling you what the result set(s) would look like were the stored procedure to be executed. Furthermore, the result set(s) might change depending on the parameters passed to the procedure when it is executed.
I am not getting your question clearly I think this would work with you
Select *
from sys.objects
where type='p' and name = (procedure name)
Replace your query with this and it will work fine
I've created various code generators that use the output of stored procs. In my experience, most procedures that SELECT anything output their schema just the same if you call them with null (DbNull.Value) as the value for all parameters. You can get the parameter list itself from system views, though I find it convenient to use INFORMATION_SCHEMA.PARAMETERS.
By executing the procedure in a transaction and always rolling back you can safely execute stuff even when you have no idea what the procedure does.
You'll probably need a basic GUI and allow the user to modify the parameters - or a config file or some other way to provide parameter values for specific procedures. A stored proc may produce output with different schemas depending on the parameters, though I haven't seen many that do.
App.config
<appSettings>
<add key="Schema_Name" value ="[dev]."/> <!-- use any one [dev]. or [dbo]. -->
</appSettings>
c# read Key
string schema_Name = Configuration["Schema_Name"].ToString();
Store Procedure
SqlConnection objConn = new SqlConnection(Connection);
objConn.Open();
SqlCommand cmd = new SqlCommand("Exec WLTCVarification", objConn);
cmd.Parameters.Add("#SchemaName", SqlDbType.Text);
cmd.Parameters["#Schema_Name"].Value = schema_Name; // dev or dbo;
rowsAmount = (string)cmd.ExecuteScalar();
objConn.Close();
c# Sql Query
SqlConnection objConn = new SqlConnection(Connection);
objConn.Open();
SqlCommand cmd = new SqlCommand("select * from " + schema_Name + "receive_agv_onlyerror, objConn);
rowsAmount = (string)cmd.ExecuteScalar();
objConn.Close();

Categories