How to insert another table data from select query for exist table - ms-access-2007

Actually I'm creating one database application where if person first day login then his sales_count will be 1, same person login again then its sales_count will be 2 , same user login next day then its sales_count again 1.
For this I created two tables Login and Sales_Details. In Login I have:
User_name, Password and Unique no.
Now, in sales_details I want to fetch only User_name,Unique_no from login detail but at same time I want to increment sales_count in sales_details table also update today date.
Sales_details has
Sales_id,User_name,Unique_No,Sales_count,To_Date field
Actually I tried but nothing happen if To_date is null then insert today date+sales_count as 1 in sales_details
Below I'm pasting my whole code:
string todaydate = DateTime.Now.ToString("dd/MM/yyyy");
string access = "select To_Date from Sales_Details";
cmd = new OleDbCommand(access, con);
con.Open();
using (OleDbDataReader read = cmd.ExecuteReader()){
while (read.Read()){
string date2 = read["To_Date"].ToString();
if (todaydate == date2){
cmd = new OleDbCommand("update Sales_Details set Sales_count= IIF(IsNull(Sales_count), 0, Sales_count) + 1, [To_Date]=Date() where [Unique_No]=#Unique_No", con);
cmd.Parameters.AddWithValue("#Unique_No", txtinput.Text);
con.Open();
int n = cmd.ExecuteNonQuery();
if (n == 0) {
MessageBox.Show("Invalid Unique No.");
} else {
this.DialogResult = DialogResult.OK;
}
con.Close();
} else {
int counter=1;
cmd = new OleDbCommand("insert into Sales_Details select User_name,Unique_No from Login where Unique_No=#Unique_No Union select ISNULL(Sales_Count+1,0) as [#Sales_Count],DATE() AS [To_date]", con);
cmd.Parameters.AddWithValue("#Unique_No", txtinput.Text);
cmd.Parameters.AddWithValue("#Sales_count",counter);
int n1 = cmd.ExecuteNonQuery();
if (n1 == 0){
MessageBox.Show("Invalid Unique No.");
} else {
this.DialogResult = DialogResult.OK;
}
}
}
}
con.Close();

Related

SQL Server DataAdapter is not filling datatable

I am running code to fill a dataset from a SQL Server table, but for some reason it is not filling the datatable. I have run the stored procedure with the values when stepping through the code and it returns rows. I have checked via SQL Server Profiler what command runs and then executed the same command through SQL Server Management Studio and it returns rows, but for some reason in Visual Studio it returns no rows, yet it is not returning any exception.
The code is :
try
{
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["Intranet"].ConnectionString))
{
switch (command)
{
case "radiobutton":
string school = ParameterString[0];
using (SqlDataAdapter da = new SqlDataAdapter(GET_TEMPLATE_NAMES, cnn))
{
DataTable dt = new DataTable();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.AddWithValue("#TemplateforSchool", school);
cnn.Open();
da.Fill(dt);
lstTemplates.DataSource = dt;
lstTemplates.DataBind();
}
break;
case "listbox": // If the listbox triggers the callback then update the grid
switch (radSchools.SelectedItem.Text)
{
case "Junior School":
StartYear = 1;
EndYear = 5;
break;
case "Middle School":
StartYear = 6;
EndYear = 8;
break;
case "Senior School":
StartYear = 9;
EndYear = 12;
break;
}
string TemplateName = ParameterString[0];
int DetentionCount = Convert.ToInt16(ParameterString[1]);
string DetentionType = ParameterString[2];
using (SqlDataAdapter da = new SqlDataAdapter(GET_CAREGIVER_EMAIL_LIST, cnn))
{
DataTable dt = new DataTable();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#DetentionType",
SqlDbType = SqlDbType.VarChar,
Value= DetentionType
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName="#DetentionCounter",
SqlDbType=SqlDbType.Int,
Value=DetentionCount
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#StartYear",
SqlDbType = SqlDbType.Int,
Value = StartYear
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#EndYear",
SqlDbType = SqlDbType.Int,
Value = EndYear
});
cnn.Open();
da.Fill(dt);
gdvCaregiverEmailList.DataSource = dt;
gdvCaregiverEmailList.DataBind();
}
break;
}
}
}
catch(Exception ex)
{
}
The problem is in the listbox: section of the switch statement. The SqlDataAdapter works fine in the radio button section of the switch.
I am not sure what I am missing so any help would be much appreciated.
I have checked SqlDataAdapter does not fill DataSet and also SqlDataAdapter not filling DataTable but the first was not relevant to my situation and the second had no accepted answer that I could find.
The SQL Server stored procedure that I am calling is
ALTER PROCEDURE [dbo].[GetCaregiverEmailList]
#DetentionType CHAR(2),
#DetentionCounter INT,
#StartYear INT,
#EndYear INT
AS
BEGIN
SELECT DISTINCT
sdc.StudentCode, s.Student#, s.GIVEN_NAME, s.SURNAME,
sdc.DetentionCount, sdc.DetentionType,
s.GIVEN_NAME + ' ' + s.SURNAME AS FullName,
LTRIM(s.CURRENT_YEAR) AS CurrentYear,
i.EMAIL_HOME, RTRIM(i.SALUTATION) AS EmailTitle,
ax.CORR_PREFERENCE, ar.CAREGIVER_NO
FROM
StudentDetentionCounter sdc
LEFT JOIN
[PCSchool].[dbo].[Student] s ON sdc.StudentCode = s.STUDENT#
INNER JOIN
[PCSchool].[dbo].[ALUMREL] ar ON sdc.StudentCode = ar.CHILD#
LEFT JOIN
[PCSchool].[dbo].[IDENTITY] i ON ar.PARENT# = i.[MEMBER#]
LEFT JOIN
[PCSchool].[dbo].[ALUMREL_EX] ax ON ar.parent# = ax.PARENT#
WHERE
(ar.PARENT# <> ar.FAMILY_HASH)
AND ar.EN_EMAIL IN ('I','A')
AND (ax.CORR_PREFERENCE = 1)
AND (sdc.DetentionCount = #DetentionCounter
AND sdc.DetentionType = #DetentionType)
AND (CONVERT(INT, (LTRIM(s.CURRENT_YEAR))) BETWEEN #StartYear AND #EndYear)
ORDER BY
s.SURNAME
END
The command that is executed when I look at SQL Server Profiler is
exec GetCaregiverEmailList #DetentionType='LT',#DetentionCounter=3,#StartYear=9,#EndYear=12
And the following are the rows that are returned if I execute the stored procedure manually or running the above exec command.
Any suggestions or help would be much appreciated.
Regards,
Darren

How can I split a string value and insert it in a different column in the same row?

i have column like this (all in varchar)
SIGN ON SIGN OFF SIGN IN SIGN OFF
----------------------- -------- -----------
01-05-2015 / 20-04-2016 NULL NULL
AND i want to do this:
SIGN ON SIGN OFF SIGN IN SIGN OFF
----------------------- -------- -----------
01-05-2015 / 20-04-2016 01-05-2015 20-04-2016
i try with string split from sql 2016 but he had on another line the values not the same.
how can i do it?
You can try below -
DEMO
select
left(colname,charindex('/',colname)-1) as signon,
right(colname,charindex('/',colname)-1) as signoff
from tablename
OUTPUT:
signon signoff
01-05-2015 20-04-2016
You can use string functions:
select col1,
left(col1, charindex('/', col1) - 1),
stuff(col1, 1, charindex('/', col1) + 1, '')
from t;
You can try the following query.
select substring([SIGN ON SIGN OFF],1,charindex('/',[SIGN ON SIGN OFF])-2) as sign_in,
substring([SIGN ON SIGN OFF],charindex('/',[SIGN ON SIGN OFF])+1,len([SIGN ON SIGN OFF])) as sign_off
if i enter manually both answers worked. but for some reason executing was give me an error. so i give up from trying in the Sql code i did in c#.
here my solution that worked fo all cells.
DBHelper.DBHelper da = new DBHelper.DBHelper();
DataTable dt = new DataTable();
dt = da.getAllEmbarques();
foreach (DataRow row in dt.Rows)
{
try
{
List<SqlParameter> p = new List<SqlParameter>();
string nospaces = row[5].ToString().Replace(" ", string.Empty);
string[] newsplit = nospaces.Split('/');
if (newsplit.Count() == 1)
{
string[] newsplit1 = newsplit[0].ToString().Split('-');
DateTime dt1 = new DateTime(Int32.Parse(newsplit1[0]), Int32.Parse(newsplit1[1]), Int32.Parse(newsplit1[2]));
SqlParameter parameter = new SqlParameter("#SIGNIN",SqlDbType.DateTime);
parameter.IsNullable = true;
parameter.Value = dt1;
p.Add(parameter);
parameter = new SqlParameter("#SIGNOFF", SqlDbType.DateTime);
parameter.IsNullable = true;
parameter.Value = DBNull.Value;
p.Add(parameter);
p.Add(new SqlParameter("#id", row[7].ToString()));
da.UpdateStringsplitEmbarques(p.ToArray());
}
else
if (newsplit.Count() == 2)
{
string[] newsplit1 = newsplit[0].ToString().Split('-');
string[] newsplit2 = newsplit[1].ToString().Split('-');
DateTime dt1 = new DateTime(Int32.Parse(newsplit1[0]), Int32.Parse(newsplit1[1]), Int32.Parse(newsplit1[2]));
DateTime dt2 = new DateTime(Int32.Parse(newsplit2[0]), Int32.Parse(newsplit2[1]), Int32.Parse(newsplit2[2]));
SqlParameter parameter = new SqlParameter("#SIGNIN", SqlDbType.DateTime);
parameter.IsNullable = true;
parameter.Value = dt1;
p.Add(parameter);
parameter = new SqlParameter("#SIGNOFF", SqlDbType.DateTime);
parameter.IsNullable = true;
parameter.Value = dt2;
p.Add(parameter);
p.Add(new SqlParameter("#id", row[7].ToString()));
da.UpdateStringsplitEmbarques(p.ToArray());
}
}
catch
{
}
}
thanks you all for the time spending answering my question.
best regards

Get summarized/sorted data from SQL Server in ASP.NET

below is my sql table in which I'm saving student attendance
I'm trying to create a summarized attendance report as below:
Attendance Summary of all students:
Number of students present in class I: 1
Number of students present in class II: 1
Number of students present in class III: 0
But I don't exactly am finding a right way to do it. below is the sample code I'm trying to use to achieve this:
public void GetPresentCount()
{
using (SqlConnection con = new SqlConnection(constring))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("select count(*) as 'TotalPresent' from stud_att where att='Present' and a_date='"+ systemdate +"'", con))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
{
totstuds.InnerText = dr["TotalCount"].ToString();
}
else
{
totstuds.InnerText = "0";
}
}
}
con.Close();
}
}
public void GetAbsentCount()
{
using (SqlConnection con = new SqlConnection(constring))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("select count(*) as 'TotalPresent' from stud_att where att='Present' and a_date='" + systemdate + "'", con))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
{
totstuds.InnerText = dr["TotalCount"].ToString();
}
else
{
totstuds.InnerText = "0";
}
}
}
con.Close();
}
}
But I know this is not the right way.
I think you just want conditional aggregation:
select class,
sum(case when att = 'Present' then 1 else 0 end) as attendance
from stud_att
where a_date = ?
group by class
order by class;
The ? is a parameter placeholder to pass in the date. Don't munge SQL queries with constant values; pass them in as parameters.

Update SQL table very slow

I have problem when I try to update SQL table with
I have datagridview and I need to update SQL table and take the value form my datagridview . my datagridview have more than 10000 rows
I take time more than 1:30 hour very slow
datagridview name "dgv_balance"
Here is the code:
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = "My Connection"
cn.Open();
using (SqlCommand cmd_select = new SqlCommand())
{
for (int i = 0; i < dgv_balance.RowCount; i++)
{
cmd_select.Connection = cn;
cmd_select.CommandType = CommandType.StoredProcedure;
cmd_select.CommandText = "clients_balances_select_glid_date";
cmd_select.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_select.Parameters.AddWithValue("#date", Convert.ToDateTime(dgv_balance.Rows[i].Cells[2].Value));
if (cmd_select.ExecuteScalar().ToString()=="")
{
using (SqlCommand cmd_insert = new SqlCommand())
{
cmd_insert.Connection = cn;
cmd_insert.CommandType = CommandType.StoredProcedure;
cmd_insert.CommandText = "clients_balances_insert_data";
cmd_insert.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_insert.Parameters.AddWithValue("#name", Convert.ToString(dgv_balance.Rows[i].Cells[1].Value));
cmd_insert.Parameters.AddWithValue("#date", Convert.ToString(dgv_balance.Rows[i].Cells[2].Value));
cmd_insert.Parameters.AddWithValue("#balance", Convert.ToString(dgv_balance.Rows[i].Cells[3].Value));
cmd_insert.ExecuteNonQuery();
cmd_insert.Parameters.Clear();
}
}
else
{
using (SqlCommand cmd_update= new SqlCommand())
{
cmd_update.Connection = cn;
cmd_update.CommandType = CommandType.StoredProcedure;
cmd_update.CommandText = "clients_balances_update_balance";
cmd_update.Parameters.AddWithValue("#glid", Convert.ToString(dgv_balance.Rows[i].Cells[0].Value));
cmd_update.Parameters.AddWithValue("#date", Convert.ToString(dgv_balance.Rows[i].Cells[2].Value));
cmd_update.Parameters.AddWithValue("#balance", Convert.ToString(dgv_balance.Rows[i].Cells[3].Value));
cmd_update.ExecuteNonQuery();
cmd_update.Parameters.Clear();
}
}
cmd_select.Parameters.Clear();
}
}
}
You may have to call SELECT command for one time only before you loop through your datagridview rows and cache the result data and check on the result while iterating your datagridview instead of calling it on each row. This way you will reduce your commands by 10000.
It also better if you could show us your procedures' queries.
Or if your datagridview is the ONLY source for your data then you can delete all your previous data in your database and make one insert call for all of your datagridview data.
Try this:
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString = "MyConnection" ;
cn.Open();
SqlDataAdapter da = new SqlDataAdapter();
DataTable dt = new DataTable();
using (SqlCommand cmd_select = new SqlCommand())
{
cmd_select.Connection = cn; cmd_select.CommandType = CommandType.StoredProcedure; cmd_select.CommandText = "clients_balances_select_glid_date";
da.SelectCommand = cmd_select;
da.Fill(dt);
for (int i = 0; i < dgv_balance.RowCount; i++)
{
if(/* check here if dt contains this row*/)
{
// Insert
}
else
{
// Update
}
}
}
}
I think you should insert or update all data one time.
Create index for glId column. If glId is primary key, it's indexed.
Assumes that List ClientBalance is list items you need update or insert.
public class ClientBalance
{
GlId int {get;set;}
ClientName string {get;set;}
Balance decimal {get;set;}
DateInput DateTime {get;set;}
}
You could serialize list Item to xml string and pass it to store procedure
public string Serialize<T>(T value) where T : new()
{
var serializeXml = string.Empty;
if (value != null)
{
try
{
var xmlserializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
var writer = XmlWriter.Create(stringWriter);
xmlserializer.Serialize(writer, value);
serializeXml = stringWriter.ToString();
writer.Close();
}
catch (Exception ex)
{
return string.Empty;
}
}
return serializeXml;
}
Create a new store procedure for insert or update item like that:
CREATE PROCEDURE [dbo].[clients_balances_insert_or_update]
(
#xmlObject nvarchar(max)
)
AS
BEGIN
-- TABLE INCLUDE DATE FROM XML
DECLARE #tblBalances AS TABLE
(
GlId int,
DateInput datetime,
ClientName nvarchar(50),
Balance decimal(18,2)
)
DECLARE #idoc int -- xml id
-- PARSE XML TO OBJECT
EXEC sp_xml_preparedocument #idoc OUTPUT, #xmlObject
INSERT INTO #tblBalances
(
GlId, DateInput, ClientName, Balance
)
SELECT s.GlId, s.DateInput, s.ClientName, s.Balance
FROM OPENXML (#idoc, '/ArrayOfClientBalance/ClientBalance', 8) WITH (
GlId int 'GlId',
DateInput datetime 'DateInput',
ClientName NVARCHAR(50) 'ClientName',
Balance DECIMAL(18,2) 'Balance'
) s
EXEC sp_xml_removedocument #idoc
-- USE MERGE FOR INSERT OR UPDATE DATE
-- Use transaction
BEGIN TRAN InsertOrUpdate
BEGIN TRY
MERGE Target AS T
USING #tblBalances AS S
ON (T.GlId = S.GlId)
WHEN NOT MATCHED BY TARGET
THEN INSERT( GlId, DateInput, ClientName, Balance) VALUES( GlId, DateInput, ClientName, Balance)
WHEN MATCHED
THEN UPDATE SET DateInput = S.DateInput, Balance = s.Balance
COMMIT TRAN InsertOrUpdate;
END TRY
BEGIN CATCH
ROLLBACK TRAN InsertOrUpdate;
THROW;
END CATCH
END
Hope this helpfully!

SQL command INSERT doesn't insert data into table, but debug shows it did (C#)

I can't get what is happening to my app. I'm using a SQL CE (.sdf file) to a local database (winform app) and when I debug, everything runs pretty well, I have in the end of it the message that my data was inserted well. But later on, when I check my databse, its empty.
What should I do?
This is my code:
SqlCeConnection conn = new SqlCeConnection(#"Data Source=|DataDirectory|\Database\Livraria.sdf;");
SqlCeCommand cmd = new SqlCeCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"INSERT INTO Livros (Codigo, ISBN, Titulo, Editora, Localizacao, Valor, QTD, Autor, AutorEspiritual, Data_)
VALUES (#Codigo, #ISBN, #Titulo, #Editora, #Localizacao, #Valor, #QTD, #Autor, #AutorEspiritual, #Data_)";
cmd.Parameters.AddWithValue("#Codigo", codigo);
cmd.Parameters.AddWithValue("#ISBN", isbn);
cmd.Parameters.AddWithValue("#Titulo", titulo);
cmd.Parameters.AddWithValue("#Editora", editora);
cmd.Parameters.AddWithValue("#Localizacao", localizacao);
cmd.Parameters.AddWithValue("#Valor", valor);
cmd.Parameters.AddWithValue("#QTD", entradas);
cmd.Parameters.AddWithValue("#Autor", autor);
cmd.Parameters.AddWithValue("#AutorEspiritual", autorEspiritual);
cmd.Parameters.AddWithValue("#Data_", data_);
try
{
conn.Open();
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Livro adicionado com sucesso!");
}
else
{
MessageBox.Show("O livro não foi adicionado.");
}
// Reset campos
Codigo.Text = "";
Titulo.Text = "";
Editora.SelectedIndex = 0;
Valor.SelectedIndex = 0;
Localizacao.SelectedIndex = 0;
Entrada.Text = "";
Isbn.Text = "";
Autor.SelectedIndex = 0;
AutorEspiritual.SelectedIndex = 0;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
conn.Close();
}
You have two databases. You are inserting to one and looking for the results in another.
Or, you are starting a transaction, inserting but then not committing.
The first thing you need to do is to create a simple select statement first that gets record from you sqlce database.
if( has record//connected )
{
//Proceed to your insert statement remove if else and use
conn.Open();
cmd.ExecuteNonQuery()
//then check your DB again
}
else
{
//Problem on you connection string
}
Your sqlce database is located on your bin folder
Regards