getting Schema of one Table in C# - c#

I want to get Schema for a table with name "Petro" in SQL SErver
after initializing connectionString, I use this Code
conn.open();
conn.getSchema("Tables");
but it returns schema for all the tables. I only want the Petro schema. What should I do?

string[] restrictions = new string[4];
restrictions[2] = "Petro";
DataTable table = conn.GetSchema("Tables",restrictions);
Look here for more information: MSDN: Working with the GetSchema Methods
Edit: use GetSchema instead of getSchema

You can retrieve the schema in following way:
string sql = "select * from Petro WHERE 1 = 0";
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader reader = cmd.ExecuteReader();
DataTable schema = reader.GetSchemaTable();

SQL Server solution:
There is a store procedure called sp_columns. When you run that procedure with the table's name as a parameter, it will return the schema just for that table.

Related

Passing DataSet to Stored Procedure

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.

How to Compare Rows Stored in a Datatable with Multiple Tables' Rows in a Local SQL DB?

I have acquired data from my Oracle server and stored it in a DataTable (u). I have verified that the correct data has been acquired and stored.
I also have a local SQL database that has multiple tables, each with a column that carries a unique identifier.
What I would like to be able to do is compare the Oracle data stored in DataTable (u) with these various local SQL database tables, and then show the values(s) within the local SQL database tables that are identical to the values within the Oracle DataTable (u).
How would I perform this comparison while being able to tell what the matches are?
My current unfinished code:
using (OracleDataAdapter b = new OracleDataAdapter(sql2, conn))
{
conn.Open();
OracleCommand cmd2 = new OracleCommand(sql2, conn) { CommandType = CommandType.Text };
cmd2.BindByName = true;
cmd2.Parameters.Add(":user_name", OracleDbType.Varchar2).Value = cboUserName.SelectedValue;
var u = new DataTable();
b.Fill(u);
lstFunctions.DisplayMember = "Function_Name";
lstFunctions.ValueMember = "Function_Name";
lstFunctions.DataSource = u;
SqlConnection sodconnstring = new SqlConnection(#"***\SODGROUPS.sdf");
sodconnstring.Open();
SqlCommand sodcommand = new SqlCommand("SELECT * FROM tbl1, tbl2", sodconnstring);
SqlDataAdapter sodAdapter = new SqlDataAdapter(sodcommand);
var sodGroupData = new DataTable();
sodAdapter.Fill(sodGroupData);
conn.Close();
sodconnstring.Close();
}
Please let me know if you require any additional input.
Thanks.
Unless you share the schema of the tables (both oracle and SQL), it would be hard to guess a solution.
This line would return the join of tbl1 and tbl2 and I'm sure to compare the values, you would n't need a join .
SqlCommand sodcommand = new SqlCommand("SELECT * FROM tbl1, tbl2", sodconnstring)

C# write datagridview data into a SQL Server table

I have a four column table in a SQL Server database. The info for the first three columns is supplied by another source. Column 4 is set to null by default.
I then have a win form with a datatable that populates with the information from the SQL Server database using the following code:
public DataTable populateFormList()
{
SqlConnection con = new SqlConnection(Properties.Settings.Default.sqlConnectionString);
SqlCommand cmd = new SqlCommand("SELECT * FROM of_formlist_raw", con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
return dt;
}
datagridview2.DataSource = populateFormList();
datagridview2.Refresh();
Now that works fine in obtaining my data.
The user can then make changes to the null values in column 4.
How can I easily write these changes from the datatable back into the SQL Server table?
In other words, once the on screen datatable has additional values, how can I then store the updated information back in the SQL Server database from which it was originally obtained from?
Thanks.
Try something like this and just pass (DataTable)datagridview2.DataSource as the data table:
private static void BulkInsertToSQL(DataTable dt, string tableName)
{
using (SqlConnection con = new SqlConnection(_DB))
{
SqlBulkCopy sbc = new SqlBulkCopy(con);
sbc.DestinationTableName = tableName;
//if your DB col names don’t match your data table column names 100%
//then relate the source data table column names with the destination DB cols
sbc.ColumnMappings.Add("DBAttributeName1", "DTColumnName1");
sbc.ColumnMappings.Add("DBAttributeName2", "DTColumnName2");
sbc.ColumnMappings.Add("DBAttributeName3", "DTColumnName3");
sbc.ColumnMappings.Add("DBAttributeName4", "DTColumnName4");
con.Open();
sbc.WriteToServer(dt);
con.Close();
}
}
2 options, with or without TableAdapter.
I would recommend to read this in MSDN for TableAdapter
They're using BindingSources too, which are excellent components, easy-to-use.
Without TableAdapter, read this, the "Update Records Using Command Objects" part.

Problem with ADO.NET UPDATE code

Could somebody take a quick peek at my ado.net code? I am trying to update the row from a dataset, but it just isn't working. I am missing some elemental piece of the code, and it is just eluding me. I have verified that the DataRow actually has the correct data in it, so the row itself is accurate.
Many thanks in advance.
try
{
//basic ado.net objects
SqlDataAdapter dbAdapter = null;
DataSet returnDS2 = new DataSet();
//a new sql connection
SqlConnection myConn = new SqlConnection();
myConn.ConnectionString = "Server=myserver.mydomain.com;"
+ "Database=mydatabase;"
+ "User ID=myuserid;"
+ "Password=mypassword;"
+ "Trusted_Connection=True;";
//the sqlQuery
string sqlQuery = "select * from AVLUpdateMessages WHERE ID = 21";
//another ado.net object for the command
SqlCommand cmd = new SqlCommand();
cmd.Connection = myConn;
cmd.CommandText = sqlQuery;
//open the connection, execute the SQL statement and then close the connection.
myConn.Open();
//instantiate and fill the sqldataadapter
dbAdapter = new SqlDataAdapter(cmd);
dbAdapter.Fill(returnDS2, #"AVLUpdateMessages");
//loop through all of the rows; I have verified that the rows are correct and returns the correct data from the db
for (int i = 0; i <= returnDS2.Tables[0].Rows.Count - 1; i++)
{
DataRow row = returnDS2.Tables[0].Rows[i];
row.BeginEdit();
row["UpdatedText"] = #"This is a test...";
row.EndEdit();
}
//let's accept the changes
dbAdapter.Update(returnDS2, "AVLUpdateMessages");
returnDS2.AcceptChanges();
myConn.Close();
}
I think you need an update query in your data adapter. I know, this sucks... Alternatively you can use CommandBuilder class to automatically generate queries for CRUD operations.
example at: http://www.programmersheaven.com/2/FAQ-ADONET-CommandBuilder-Prepare-Dataset
You might be able to use SqlCommandBuilder to help out. After the Fill call, add the following statement. That will associate a command builder with the data adapter and (if there is a primary key available) it should generate the update statement for you. Note that there is some expense behind the command builder. It may not be much relative to everything else, but it does involve looking at schema information (to get primary key information, field names, field types, etc.) for the table and generating INSERT, DELETE, and UPDATE statements involving all fields in the table.
SqlCommandBuilder cb = new SqlCommandBuilder(dbAdapter);
Wait, why not something like
update AVLUpdateMessages set UpdatedText = 'This is a test...' where id = 21
If you're picking through all the rows of a table to update one at a time, you're probably doing it wrong. SQL is your friend.

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