C# How to Retrieve DateSet Value in SqlDataAdapter? - c#

In the development, I intent to retrieve the Index Key from SQL Server Database and apply to the local.sdf database. However, I failed to retrieve the Index Key from SQL Server Database. So, how could i retrieve the value stored in DataSet?
E.g: tableName = "ProductTable", indexName = "IX_product".
Or my SqlDataAdapter doesn't return any value?
P/s: I understand that there are numerous of working tutorial in forum and stackoverflow, unfortunately, i couldn't get it worked.
private void btnGetSchema_Click(object sernder, RoutedEventArgs e)
{
SyncDbSchema();
}
private void SyncDbSchema()
{
// setIndexSchema();
DataSet dsIndex = getIndexSchema();
MessageBox.Show("Table Row Count : " + dsIndex.Tables["tbIndex"].Rows.Count);
for (int i = 0; i < dsIndex.Tables[0].Rows.Count; i++)
{
string tableName = dsIndex.Tables[0].Rows[i]["TableName"].ToString();
string indexName = dsIndex.Tables[0].Rows[i]["IndexName"].ToString();
string indexType = dsIndex.Tables[0].Rows[i]["IndexType"].ToString();
}
}
public DataSet getIndexSchema()
{
SqlConnection conn = new SqlConnection(lblServerCon.Content.ToString());
DataSet dataSet = new DataSet();
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
conn.Open();
sqlDataAdapter = new SqlDataAdapter(String.Format(#"USE SyncServer SELECT T.[name] AS [TableName], I.[name] AS [IndexName],
COL_NAME(T.[object_id], IC.[column_id]) AS [ColumnName], I.[type] AS [IndexType], I.[is_unique] AS [Unique]
FROM sys.tables T INNER JOIN [sys].[indexes] I ON I.[object_id] = T.[object_id]
AND I.[is_primary_key] = '0'
INNER JOIN [sys].[index_columns] IC ON IC.[object_id] = T.[object_id]
AND IC.[index_id] = I.[index_id]"), conn);
sqlDataAdapter.FillSchema(dataSet, SchemaType.Source,"tbIndex");
conn.Close();
return dataSet;
}
The query is perfect working in T-SQL and get the result that i intent to retrieve.
TableName IndexName ColumnName IndexType Unique
tbReport IX_tbReport_SID SalesID 2 0
tbReport IX_tbReport_RID ReportID 2 0

Are you sure that you want to use FillSchema?
Why not just?
adapter.Fill(dataSet);
Of course you can combine them first FillSchema (but why you need it?), next data (just Fill)

Related

How to solve Column 'empID' does not belong to table?

I have an Employee table in my sql database which has emp_Id, emp_name, manager_Id.
I'm trying to get all the emp_name as a LIST and put them in a ComboBox
here my sql statement:
string sql = "SELECT emp_name FROM Employee";
And this how i'm putting them in the LIST
public static List<T> GetList<T>(DataTable dt)
where T : IPopulateColumns, new()
{
List<T> TList = new List<T>();
foreach (DataRow dr in dt.Rows)
{
T t1 = new T();
t1.PopulateColumns(dr);
TList.Add(t1);
}
return TList;
Here my PopulateColumns method inside the Employee Class: I have fields and properties name for empId, empName, managerID inside the class.
public void PopulateColumns(DataRow dr)
{
this.empId = (int)dr["EmpId"];
this.empName = dr["EmpName"].ToString();
this.managerId = dr["ManagerID"].ToString();
}
I getting an error that stated " Columnn 'EmpId ' does not belong to table
Since I don't have the completed code you provided, I recommend you use the following code
to get get all the emp_name as a LIST and add them as the datasource of the combobox.
Code:
private void Form1_Load(object sender, EventArgs e)
{
string connstring = #"";
SqlConnection connection = new SqlConnection(connstring);
connection.Open();
string sql = "SELECT emp_name FROM Employee";
SqlCommand command = new SqlCommand(sql, connection);
DataSet set = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(set);
var result = set.Tables[0].AsEnumerable().Select(i=>i.Field<string>("emp_name")).ToList();
comboBox1.DataSource = result;
}

how to create an id to be shown in the text box based on selected dropdownlist

i would like to create an id generator based on their department selected from the dropdownlist. lets say my ddl has 3 departments (A,B,C) and when generating an id it will be A20181001 and then A20181002 upon submission but when i pick B from the ddl after sending A20181001 to the database, it will be B20181001.
so far i have created the code for the increment for the id without the departments. here is the code i did so far. (I used the date for today so the 20181001 is just an example):
void getMRF_No()
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
int mrf = 0;
int i;
string a;
//string x = Request.QueryString["BUnit"];
string mrfNo = "";
database db = new database();
string conn = dbe.BU();
SqlConnection connUser = new SqlConnection(conn);
SqlCommand cmd = connUser.CreateCommand();
SqlDataReader sdr = null;
string query = "SELECT TOP 1 MRF_NO FROM incMRF ORDER BY MRF_NO DESC";
connUser.Open();
cmd.CommandText = query;
sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr.GetInt32(0).ToString();
}
if (mrfNo == "")
{
mrfNo = Convert.ToString(year) + "" + 00;
}
mrf += 0;
i = Convert.ToInt32(mrfNo) + 1;
a = i.ToString();
txtMRFNo.Text = a;
connUser.Close();
}
any help to improve this code will be helpful. thank you :)
EDIT:
here is the dropdown list code:
void SelectBU()
{
string database = dbe.BU ();
using (SqlConnection con = new SqlConnection(database))
{
con.Open();
string query = "select BUnit from BusinessUnit";
using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
{
DataSet ds = new DataSet();
sda.Fill(ds, "BUnit");
ddlBu.DataSource = ds;
ddlBu.DataTextField = "BUnit";
ddlBu.DataValueField = "BUnit";
ddlBu.DataBind();
selectOption(ddlBu, "Select Dept");
}
con.Close();
}
}
EDIT2: I will state what im searching for here incase some doesnt know or understand. What i want is upon selecting a department from a dropdownlist, for example i picked A. the textbox show show A2018102201. if i select B it should show B2018102201 and if its C then c2018102201. and it will change its number once i submit it to a database and a new form loads. So if A2018102201 is already in the database, then the text shown in the text box will be A2018102202. BUT if i select B then the textbox will show B2018102201 since it does not exist in the database yet.
First you should get max ID, then increase the numeric part of your Id, and If this is a multi-user application, you have to lock your table, because it might create many ID duplication, Therefore I'm not recommend to create ID like this on c#, it is better to create a Sequence on SQL server. but I wrote this sample for you, just call it with proper value.
static string getMRF_No(string prefixCharFromDropDownList)
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
string mrfNo = "";
SqlConnection connUser = new SqlConnection("Server=130.185.76.162;Database=StackOverflow;UID=sa;PWD=$1#mssqlICW;connect timeout=10000");
SqlCommand cmd = new SqlCommand(
$"SELECT MAX(MRF_NO) as MaxID FROM incMRF where MRF_NO like '{prefixCharFromDropDownList}%'"
,connUser
);
connUser.Open();
SqlDataReader sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr["MaxID"].ToString();
}
if (mrfNo == "")
{
mrfNo = prefixCharFromDropDownList + year + "000";
}
else
{
mrfNo = prefixCharFromDropDownList + (long.Parse(mrfNo.Substring(1)) + 1).ToString().PadLeft(2);
}
sdr.Close();
cmd = new SqlCommand($"INSERT INTO incMRF (MRF_NO) values ('{mrfNo}')",connUser);
cmd.ExecuteNonQuery();
connUser.Close();
//txtMRFNo.Text = prefixCharFromDropDownList + i.ToString();
return mrfNo;
}
I call this method on a console application as test.
static void Main(string[] args)
{
// send dropdown (selected char) as prefix to method
var newAId = getMRF_No("A");
var newAnotherAId = getMRF_No("A");
var newBId = getMRF_No("B");
var newAnotherAId2 = getMRF_No("A");
Console.ReadKey();
}

Winforms: How to query a database with a sql function using SqlCommand?

I have a method which takes a single string parameter (ID).
I want to use SqlCommand to return a DataTable of results from a query. I'm trying to call a table function from my database (Sql Server) in the query and pass in my ID parameter. The contents of this DataTable will then populate a Combobox. Here's what I have so far...
public string populateCompanyTransSellingEntityLookUp(string BlockId)
{
string _sql = "";
SqlCommand _comm = new SqlCommand();
_comm.Parameters.AddWithValue("(#block_id", BlockId);
_comm.CommandText = "SELECT [name] FROM dbo.fnGetBlockCompanyWIList(#block_id) ORDER BY [name]; ";
_comm.Connection = _conn;
_comm.CommandTimeout = _command_timeout;
DataTable dt = new DataTable();
try
{
SqlDataReader myReader = _comm.ExecuteReader();
dt.Load(myReader);
}
catch (Exception)
{
throw;
}
Combo.DataSource = dt;
return _sql;
}
But i'm getting a error, "Must declare scalar variable '#block_id'". why?
You have an extra bracket here, you should remove it:
_comm.Parameters.AddWithValue("(#block_id", BlockId);
^^^
And perhaps it doesn't matter but give value to your parameter after you set the CommandText:
_comm.CommandText = "SELECT [name] FROM dbo.fnGetBlockCompanyWIList(#block_id) ORDER BY [name]; ";
_comm.Parameters.AddWithValue("#block_id", BlockId);

How to check if a field in a table already exists?

my question is very simple:
i have a SQL Table with a column name 'lastname' with fields lastname1,lastname2,lastname3...
In my c# code, i have a method that inserts in the table a row only if the field of the column lastname is not present in the table. This method in input has lastname, so for my INSERT is a parameter.
How can i compare and conseguently check if the field lastname is already in table?
Thanks
You should always use unique constraints in the table if a field must be unique. On that way you prevent duplicates always, even if the input was directly from SSMS or another application.
Then the easiest would be to handle the sql-exception that is raised according to it's number.
....
try
{
int inserted = cmd.ExecuteNonQuery();
} catch (SqlException ex)
{
if (ex.Number == 2601)
{
// show meaningful error message
MessageBox.Show("Cannot insert duplicate key row in object");
}
else
throw;
}
....
This SQL will insert a new record only if the value isn't already in the table:
INSERT INTO Your_Table ( LastName )
SELECT #NewLastName
WHERE NOT EXISTS( SELECT * FROM Your_Table WHERE LastName = #NewLastName )
There are two option one is from sql side another way is from code behind.
unfortunately you can't change your sql code i agree with #David.
from code behind you have to do something like this.
First you have to select all the data from your table and check that data. something like this.
SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con; //Your connection string"
cmd.CommandText = "Select * from table1"; // your query
cmd.CommandType = CommandType.Text;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
DataTable dt = new DataTable();
dt = ds.Tables[0];
int count=0;
for (int i = 0; i > dt.Rows.Count; i++)
{
if (Convert.ToString(dt.Rows[i]["LastName"]) == Lastname)
{
count++;
}
}
if (count > 0)
{
//insert code for data
}
else
{
var script = "alert('"+ Lastname + "already exist.');";
ClientScript.RegisterStartupScript(typeof(Page), "Alert", script, true);
// or you can use here your Update statement
}
May this will help you and you can understand.

Retrieve distinct row and declaring scalar variable

I am trying to retrieve a distinct row from my Database from a particular "deliverySerial".
However I encountered an error which prompt me to "Declare Scalar Variable ="#deliverySerial".
I had tried many other ways but still problems still persist.
Here is the connection:
public class DlDbConn
{
public DlDbConn()
{
}
public SqlConnection GetConnection()
{
SqlConnection dbConn;
dbConn = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\test.mdf;Integrated Security=True;User Instance=True");
return dbConn;
}
}
Method in the data layer:
private String errMsg;
private DlDbConn dbConn;
public testing()
{
dbConn = new DlDbConn();
}
public DataSet Details(String supplierLogo, String supplierName, String supplierAddr, int poNum, String dateSent, int deliverySerial, String deliveryDate,
int quantity, String catSerial, String catName)
{
SqlConnection conn;
StringBuilder sql;
SqlDataAdapter da;
DataSet detail;
conn = dbConn.GetConnection();
detail = new DataSet();
sql = new StringBuilder();
sql.AppendLine("SELECT * FROM (select PO.poNum, PO.dateSent, ViewDelivery.deliverySerial, Supplier.supplierName, Supplier.supplierAddr, Supplier.supplierLogo, ViewDelivery.deliveryDate, Catalog.catSerial, Catalog.catName, PO.quantity, ROW_NUMBER() OVER (PARTITION BY Catalog.catSerial ORDER BY Catalog.catSerial) AS num FROM PO INNER JOIN Supplier ON PO.supplierID = Supplier.supplierID INNER JOIN ViewDelivery ON PO.poNum = ViewDelivery.poNum INNER JOIN Catalog ON PO.catSerial = Catalog.catSerial)AS a WHERE a.num = 1 ");
sql.AppendLine("AND ViewDelivery.deliverySerial = #deliverySerial");
try
{
conn.Open();
da = new SqlDataAdapter(sql.ToString(), conn);
da.SelectCommand.Parameters.AddWithValue("#deliverySerial", deliverySerial);
da.Fill(detail);
}
catch (Exception ex)
{
errMsg = ex.Message;
}
finally
{
conn.Close();
}
return detail;
}
You must use parameter notation for MySQL i.e. ? instead of #deliverySerial in your query.
Also, table ViewDelivery not accessible in outer part of query.
Use:
AND a.deliverySerial = ?
I think your query is incorrect. Here is the Fiddle -- you can't query on ViewDelivery since it's outside of your subquery.
Try removing that from your WHERE criteria since that field is returned in your subquery:
sql.AppendLine("AND deliverySerial = #deliverySerial");
I don't think you need the "?", but I could be mistaken.
Good luck.

Categories

Resources