Selecting Multiple Tables in MS Access using C# - c#

Hello Everyone I got a little confuse about selecting multiple fields from different tables binding it in one result, for you to understand it well, i posted my code & ERD below. thank you for your response. Please tell me where did I go wrong tnx :)
Here's the ERD of Mine:
and Here's the Code:
try
{
OleDbConnection Con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=..\\MotoFix.mdb;");
OleDbCommand command = new OleDbCommand();
OleDbDataAdapter adapter = new OleDbDataAdapter();
DataTable dt = new DataTable();
Con.Open();
command.CommandText = String.Format("SELECT fn.Customer + ' ' + mi.Customer + ' ' + ln.Customer as [CUSTOMER FULLNAME], fn.Cashier + ' ' + mi.Cashier + ' ' + ln.Cashier as [CASHIER FULLNAME], prodName.Product as [PRODUCT NAME], prodDescription.Product as [PRODUCT DESCRIPTION], prodBrand.Product as [PRODUCT BRAND], prodQuantity.Transaction as [PRODUCT QUANTITY], prodTotalPrice.Transaction as [SUBTOTAL], job.Personnel as [Referral] FROM Product , [Order] , [Transaction] , Customer , Cashier , Personnel WHERE prodCode.Product = ProdCode.Order AND orderNo.Order = orderNo.Transaction AND pID.Personnel = pID.Transaction AND custID.Customer = custID.Transaction AND userID.Cashier = userID.Transaction AND sDate.Transaction = '{0}'", strDate);
command.Connection = Con;
adapter.SelectCommand = command;
adapter.Fill(dt);
Con.Close();
Con.Dispose();
gridViewTransac_1.DataSource = dt;
}
catch (Exception ex)
{
XtraMessageBox.Show(ex.Message);
}
Additional information: No value given for one or more required parameters.

I'm not a good sql query builder but shouldn't it be TableName.FieldName not the other way around ?
Anyways try to put the TableName first:
SELECT Customer.fn + ' ' + customer.mi + ' ' + customer.ln as [CUSTOMER FULLNAME]
, Cashier.f. + ' ' + Cashier.mi + ' ' + customer.ln as [CASHIER FULLNAME]
, Product.prodName as [PRODUCT NAME]
, Product.prodDescription as [PRODUCT DESCRIPTION]
, Product.prodBrand as [PRODUCT BRAND]
, Transaction.prodQuantity as [PRODUCT QUANTITY]
, Transaction.prodTotalPrice as [SUBTOTAL]
, Personnel.job. as [Referral]
FROM Product
, [Order]
, [Transaction]
, Customer
, Cashier
, Personnel
WHERE Product.prodCode = Order.ProdCode
AND Order.orderNo = Transaction.orderNo
AND Personnel.pID= Transaction.pID
AND Customer.custID = Transaction.custID
AND Cashier.userID = Transaction.userID
AND Transaction.sDate = #transDate
For #transDate you should add:
command.Parameters.AddWithValue("#transDate", someDate);
or you could simply do as you did

Related

String or binary data would be truncated. The statement has been terminated. when inserting into the table

In my application I am getting one row from table1 displaying it in the view and then after reply I am inserting the reply into table 2 and deleting the the entry from table 1 and getting the next question from table1.
I am getting the error:
String or binary data would be truncated. The statement has been terminated
in the httppost method. I have checked the values of the tempdata in the post method by applying a breakpoint and there is no problem with it.
The values in the database are of type nvarchar except the id which is of int type.
I am not able to find why I still get the error. The error shows in the execute method but I am not able to find the reason behind it.
The things that I am inserting are mostly strings and some may contain special character in the string like * , \ etc and up to 700 characters.
PS: Presently I have ignored SQL injection threat
[HttpGet]
public ActionResult Index()
{ string connstr = "Here is the connection string";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
SqlCommand cmd = new SqlCommand(" Select top(1) Id , Body , Email_subject , Queue , Intent , Tagging FROM
table1 ");
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = conn;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
var Did = reader["Id"].ToString();
TempData["id "] = Int64.Parse(Did);
TempData["subject "] = reader["Email_subject"].ToString();
TempData["body"] = reader["Body"].ToString();
TempData["intent"] = reader["Intent"].ToString();
TempData["queue"] = reader["Queue"].ToString();
TempData["tagging"] = reader["Tagging"].ToString();
}
conn.Close();
TempData.Keep();
return View();
}
[HttpPost]
public ActionResult Index(string Correctornot)
{ TempData.Keep();
string connstr = My connection String;
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
SqlCommand cmd = new SqlCommand("SET IDENTITY_INSERT table2 ON ; INSERT INTO table2 ( Id ,Body, Response ,Queue , Intent , Tagging , Email_subject) VALUES ( '" + TempData["id"] + "' , '" + TempData["body"] + "'
, '" + Correctornot + "' , '" + TempData["Queue"] + "' , '" + TempData["intent"] + "' , '" + TempData["tagging"] + "' , '" + TempData["subject"] + "');DELETE FROM table1 where Id = '" + TempData["id"] + "' ;");
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = conn;
SqlDataReader reader2 = cmd.ExecuteReader();
SqlCommand cmd2 = new SqlCommand(" Select top(1) Id , Body , Email_subject , Queue , Intent , Tagging FROM table1");
cmd2.CommandType = System.Data.CommandType.Text;
cmd2.Connection = conn;
SqlDataReader reader3 = cmd2.ExecuteReader();
while (reader3.Read())
{
var Did = reader3["Id"].ToString();
TempData["id "] = Int64.Parse(Did);
TempData["subject "] = reader3["Email_subject"].ToString();
TempData["body"] = reader3["Body"].ToString();
TempData["intent"] = reader3["Intent"].ToString();
TempData["queue"] = reader3["Queue"].ToString();
TempData["tagging"] = reader3["Tagging"].ToString(); }
conn.Close();
TempData.Keep();
return View(); }
Solution:
I was able to solve the problem but I still don't know the reason behind it.
The problem was due to the value returned by clicking the button. Though the value was not too large ( it was just "correct " and "not correct") , when i tried to insert it into the database it gave me the error .
I solved it by using a switch statement instead of directly adding it to the insert statement.
i.e
switch (Correctornot)
{
case "Correct":
sql = "Insert INTO [dbo].[Labeler_Email_For_confirmation_Agents](Body , Response , Queue , Intent , Tagging , Email_subject ) Values ( '" + TempData["body"].ToString() + "' , 'yes' , '" + TempData["queue"].ToString() + "' , '" + TempData["intent"].ToString() + "' , '" + TempData["tagging"].ToString() + "' , '" + TempData["email_subject"].ToString() + "');";
break;
case "Not Correct":
sql = "Insert INTO [dbo].[Labeler_Email_For_confirmation_Agents](Body , Response , Queue , Intent , Tagging , Email_subject ) Values ( '" + TempData["body"].ToString() + "' , 'no' , '" + TempData["queue"].ToString() + "' , '" + TempData["intent"].ToString() + "' , '" + TempData["tagging"].ToString() + "' , '" + TempData["email_subject"].ToString() + "');";
break;
}
SQL Server 2016 SP2 CU6 and SQL Server 2017 CU12
introduced trace flag 460 in order to return the details of truncation warnings.
You can enable it at the query level or at the server level.
Query level
INSERT INTO dbo.TEST (ColumnTest)
VALUES (‘Test truncation warnings’)
OPTION (QUERYTRACEON 460);
GO
Server Level
DBCC TRACEON(460, -1);
GO
From SQL Server 2019 you can enable it at database level:
ALTER DATABASE database_name
SET COMPATIBILITY_LEVEL = 150
ALTER DATABASE SCOPED CONFIGURATION
SET VERBOSE_TRUNCATION_WARNINGS = ON;
The old output message is:
Msg 8152, Level 16, State 30, Line 13
String or binary data would be truncated.
The statement has been terminated.
The new output message is:
Msg 2628, Level 16, State 1, Line 30
String or binary data would be truncated in table 'DbTest.dbo.TEST', column 'ColumnTest'. Truncated value: ‘Test truncation warnings‘'.
In a future SQL Server 2019 release, message 2628 will replace message 8152 by default.
"String or binary data would be truncated. The statement has been terminated" is reporting that one of the values you are trying to insert is too large for the SQL Column. For example, you'll see this error if you try insert "Hello, World" into a SQL Column that can only hold 4 characters. Truncate the value before inserting, or change the datatype of the SQL Column.

c# fetching database into SQL Server datatable

I have a problem with this code... I don't have the slightest clue for what is happening...
When I run this code in Visual Studio, I get an error saying:
System.InvalidCastException: 'Object cannot be cast from DBNull to other types.'
And here's the code:
conn.Open();
SqlCommand com = new SqlCommand("update lend set date_back=convert(datetime2, getdate(), 102) where client_name ='" + comboBox1.Text + "'", conn);
SqlDataAdapter da = new SqlDataAdapter("Declare #startdate smalldatetime declare #enddate smalldatetime set #startdate = (select date_lended from dbo.lend where client_name = '" + comboBox1.Text + "') set #enddate = (select date_back from dbo.lend where client_name = '" + comboBox1.Text + "') SELECT DATEDIFF(DAY, #startdate+2, #enddate)as timepassedd", conn);
DataTable dt = new DataTable();
da.Fill(dt);
foreach (DataRow DR in dt.Rows)
{
int date;
date = Convert.ToInt32(DR["timepassedd"]);
if (date > 0)
{
com = new SqlCommand("DELETE lend WHERE client_name ='"+comboBox1.Text+"'" +
"UPDATE book_list set book_stock = book_stock 1 WHERE book_name ='" + comboBox1.Text + "'",conn);
com.ExecuteNonQuery();
MessageBox.Show("You Returned the book " + date + " Days Late!" +
"please pay the fee to the front desk");
UserPanel u = new UserPanel();
u.Show();
this.Hide();
}
else if (date <= 0)
{
com = new SqlCommand("DELETE lend WHERE client_name ='" + comboBox1.Text + "'" +
"UPDATE book_list set book_stock = book_stock 1 WHERE book_name ='" + comboBox1.Text + "'", conn);
com.ExecuteNonQuery();
MessageBox.Show("You returned the book " + date + " Days Late!" +
"please pay the fee to the front desk");
UserPanel u = new UserPanel();
u.Show();
this.Hide();
}
}
conn.Close();
Thanks in advance
conn.Open();
SqlCommand com = new SqlCommand("update lend set date_back=convert(datetime2, getdate(), 102) where client_name ='" + comboBox1.Text + "'", conn);
SqlDataAdapter da = new SqlDataAdapter("Declare #startdate smalldatetime declare #enddate smalldatetime set #startdate = (select date_lended from dbo.lend where client_name = '" + comboBox1.Text + "') set #enddate = (select date_back from dbo.lend where client_name = '" + comboBox1.Text + "') SELECT DATEDIFF(DAY, #startdate+2, #enddate)as timepassedd", conn);
DataSet ds = new DataSet();
da.Fill(ds);
if(ds.Tables.Count == 1)
{
if(ds.Tables[0].Rows.Count > 0)
{
foreach(DataRow dr in ds.Tables[0].Rows)
{
if(dr.ItemArray.Length > 0)
{
if(dr["timepassedd"] != DBNull.Value)
{
int date;
date = Convert.ToInt32(Dr["timepassedd"]);
if (date > 0)
{
com = new SqlCommand("delete lend where client_name ='" + comboBox1.Text + "'" +
"UPDATE book_list set book_stock = book_stock 1 WHERE book_name ='" + comboBox1.Text + "'", conn);
com.ExecuteNonQuery();
MessageBox.Show("You Returned the book " + date + " Days Late!" +
"please pay the fee to the front desk");
UserPanel u = new UserPanel();
u.Show();
this.Hide();
}
else if (date <= 0)
{
com = new SqlCommand("delete lend where client_name ='" + comboBox1.Text + "'" +
"UPDATE book_list set book_stock = book_stock 1 WHERE book_name ='" + comboBox1.Text + "'", conn);
com.ExecuteNonQuery();
MessageBox.Show("You Returned the book " + date + " Days Late!" +
"please pay the fee to the front desk");
UserPanel u = new UserPanel();
u.Show();
this.Hide();
}
}
}
}
}
}
conn.Close();
You should check for DBNull value, if the column is null-able in the database a DBNull.Value will be returned instead! So you should check this column for such a value before dealing with it
Also, you shouldn't accept values from the user input and directly injecting them into the SQL query! ADO.Net. Has something called Sql Parameters it can be found in the property Parameters in the SqlCommand class. You should use this property to add values from user as parameters to the query
For Example, client name can be added like this:
com.Parameters.Add(new SqlParameter("client_name", comboBox1.Text));
Now you tell the Sql Command that the value is actually presented in the SqlParameters collection like this:
SqlCommand com = new SqlCommand("update lend set date_back=convert(datetime2, getdate(), 102) where client_name ='#client_name'", conn);
Take a look at this question Why do we always prefer using parameters in the SQL statements?
This is a MSDN reference for the Parameters property
Run code below the answer will be obvious :
string sql1 = "update lend set date_back=convert(datetime2, getdate(), 102) where client_name ='" + comboBox1.Text + "'";
Console.WriteLine(sql1);
Console.ReadLine();
SqlCommand com = new SqlCommand(sql1, conn);
string sql2 = "Declare #startdate smalldatetime declare #enddate smalldatetime set #startdate = (select date_lended from dbo.lend where client_name = '" + comboBox1.Text + "') set #enddate = (select date_back from dbo.lend where client_name = '" + comboBox1.Text + "') SELECT DATEDIFF(DAY, #startdate+2, #enddate)as timepassedd"
Console.ReadLine();
SqlDataAdapter da = new SqlDataAdapter(sql2, conn);
set #startdate = (select date_lended from dbo.lend where client_name = '" + comboBox1.Text + "')
set #enddate = (select date_back from dbo.lend where client_name = '" + comboBox1.Text + "')
a) vulnerable to unexpected behaviour if comboBox1.Text was ever to contain ' characters
b) both will result in #startdate or #enddate being NULL if there are no records matching what's selected in the combobox, which then produces a NULL value for '#datepassedd', hence your error when trying to convert to an int.
c) you don't need to query the database twice, you can just do
select DATEDIFF(DAY, date_lended+2, date_back) as timepassedd FROM dbo.lend where client_name = #clientName
(#clientName can then be added a as parameter)
In this case, there will be no rows returned if no records match the name. BTW there was never any need to use a DataTable and iterate through the records, as your query as it is now only ever returns a single row.

How to convert mysql query into acceptable c# string?

Im creating columns using mysql dynamically if column doesnt exist.. I got the code which works in mysql console but when it comes to c# its giving me "Fatal encountered during command execution"
SET #preparedStatement = (SELECT IF(
(SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tableName'
AND table_schema = DATABASE()
AND column_name = 'colName'
) > 0,
"SELECT 1",
"ALTER TABLE `tableName` ADD `colName` TINYINT(1) NULL DEFAULT '0';"
));
PREPARE alterIfNotExists FROM #preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
above code i converted into c# string as
string qry = "SET #preparedStatement = ( SELECT IF( (SELECT count(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'attendance' AND TABLE_NAME = '" + tname + "' AND COLUMN_NAME = '" + code + "_C' ) > 0, \"SELECT 1', \"ALTER TABLE " + tname + " ADD " + code + "_C int(3) NOT NULL default '0'; \" )); PREPARE alterIfNotExists FROM #preparedStatement; EXECUTE alterIfNotExists; DEALLOCATE PREPARE alterIfNotExists;";
what's the error getting?
Execution Code:
private void columnCreate_Load(object sender, EventArgs e)
{
string tname = "bca_i"; //for temprory
string code = "BCAXX";//for temprory
string qry = #"SET #preparedStatement = ( SELECT IF( (SELECT count(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'attendance' AND TABLE_NAME = '" + tname + "' AND COLUMN_NAME = '" + code + "_C' ) > 0, \"SELECT 1', \"ALTER TABLE " + tname + " ADD " + code + "_C int(3) NOT NULL default '0'; \" )); PREPARE alterIfNotExists FROM #preparedStatement; EXECUTE alterIfNotExists; DEALLOCATE PREPARE alterIfNotExists;";
try
{
using (MySqlConnection conn = new MySqlConnection(ConStr))
{
conn.Open();
using (MySqlCommand cmd = new MySqlCommand(qry, conn))
{
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The part
\"SELECT 1', \"A
does not match your original query at
"SELECT 1",
"A
Do you spot it? You replaced the " after 1 by an '.
I just figured other way for checking column exist.. Just used below query and checked if the column exists iterating through the loop of columns
string last_col = "SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'attendance' AND TABLE_NAME ='" + subCodeText.Text + "'";
where attendance is database and subCodeText.Text is my table name.

C# Excel input concatenate two columns

I have been struggling to find an answer to this. I am importing an Excel spreadsheet into C# using Oledb. This works fine, however while importing I wish to join two of the Excel columns together i.e concatenate them.
This is the code I currently have:
string PathConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + textBox1.Text + ";Extended Properties=\"Excel 12.0 XML;HDR=Yes;\";";
OleDbConnection conn = new OleDbConnection(PathConn);
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select [ID], [Subject], [Catalog], [Last], [First Name], [Descr], [Mark] from[" + textBox2.Text + "$]", conn);
DataTable dt = new DataTable();
myDataAdapter.Fill(dt);
dataGridView1.DataSource = dt;
The code above is working fine. The two columns I wish to join are Subject and Catalog and for this to be called Module. Subject is a string of three letters and Catalog four numbers. Is there a way to do this within the select statement or an alternative method?
Many thanks in advance.
Change your OleDbAdapter query like this:
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select [ID], [Subject] + ' ' + [Catalog] AS [Module], [Last], [First Name], [Descr], [Mark] from[" + textBox2.Text + "$]", conn);
Notice that [Subject] + ' ' + [Catalog] AS [Module] are combined into a single string and placed under Module alias.
You can "CONCAT" in the query:
https://msdn.microsoft.com/es-es/library/hh231515(v=sql.120).aspx
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select [ID], CONCAT( [Subject], [Catalog] ) AS subject_catalog, [Last], [First Name], [Descr], [Mark] from[" + textBox2.Text + "$]", conn);

Selecting a dropdownlist's initial value

I am trying to make the dropdownlist I have already created inside of the edit page of a formview start on the value previously selected from the sql database for the current user.
So far I have the code to populate the drop down list working correctly:
protected void ddlSelect_Init(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ReinstatementCS"].ConnectionString);
SqlCommand myCommand = new SqlCommand("SELECT Prefix, Number, ClassSection, Location, StartTime, EndTime, ClassDay, Prefix + Number + ', Section: ' + CAST(ClassSection AS VarChar) + ', Location: ' + Location + ', Start Time: ' + StartTime + ', End Time: ' + EndTime + ', Days: ' + ClassDay + ', Credits: ' + CAST(ClassCredit AS VarChar) AS PN, Capacity, GPAReqAbove1, GPAReqBelow1, CreditReqAbove30, CreditReqBelow30, ClassCredit, IsTransfer, SLN FROM Classes");
myCommand.Connection = con;
SqlDataAdapter da = new SqlDataAdapter(myCommand);
DataTable dt = new DataTable();
da.Fill(dt);
DropDownList ddlSelect = FVStudentClass.FindControl("ddlSelect") as DropDownList;
ddlSelect.DataSource = dt;
ddlSelect.DataTextField = "PN";
ddlSelect.DataValueField = "SLN";
ddlSelect.DataBind();
con.Close();
}
Where SLN is the unique value for each item in the dropdownlist and PN is the background information for each item in the dropdownlist. I want the item that is highlighted to be the PN that corresponds to what that specific user already has stored in the database. The problem is that when I try to have that value selected I am using:
protected void FVStudentClass_ModeChanging(object sender, FormViewCommandEventArgs e)
{
if (FVStudentClass.CurrentMode != FormViewMode.Edit)
return;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ReinstatementCS"].ConnectionString);
SqlCommand myCommand = new SqlCommand("SELECT Prefix + Number + ', Section: ' + CAST(ClassSection AS VarChar) + ', Location: ' + Location + ', Start Time: ' + StartTime + ', End Time: ' + EndTime + ', Days: ' + ClassDay + ', Credits: ' + CAST(ClassCredit AS VarChar) AS PN, SLN FROM Classes JOIN StudentClass on SLN = SCClass WHERE SCWSUID = " + Request.QueryString["ALWSUID"]);
myCommand.Connection = con;
SqlDataAdapter da = new SqlDataAdapter(myCommand);
DataTable dt = new DataTable();
da.Fill(dt);
DropDownList ddlSelect = new DropDownList();
ddlSelect = FVStudentClass.FindControl("ddlSelect") as DropDownList;
if (ddlSelect != null)
{
ddlSelect.DataSource = dt;
ddlSelect.Items.FindByText(dt.Rows[0]["PN"].ToString()).Selected = true;
}
con.Close();
}
but I'm still stuck because the dropdownlist does not start out with the saved value being selected. Do you know how to fix this? Am I using the wrong command (Should I use something besides ModeChanging)?
Thanks!
Try implementing the logic to select the DropDownList item on the FormView DataBound event, the ModeChanging event happens before the mode is actually changed.
You should be able to just set ddlSelect.SelectedValue to the value you want the dropdown to select.
ddlSelect.SelectedValue = dt.Rows[0]["PN"].ToString();

Categories

Resources