Initially I had commandtext defined in my ssis C# script task which counted the number of rows from table A. Now I need to add two more commandtext which counts the rows from table b and C respectively as I need to include the output of that query in my customized email.
try
{
dbConnection.Open();
if (dbConnection.State == ConnectionState.Open)
{
OleDbCommand dbCommand = dbConnection.CreateCommand();
dbCommand.CommandType = CommandType.Text;
dbCommand.CommandText = "select count(*) as Total_Source from [dbo].A";
dbCommand.CommandText = "select count(*) as Total_Destination from [dbo].B";
dbCommand.CommandText = "select count(*) as Total_Blank from [dbo].C where ColumnA = ''";
OleDbDataReader dbReader = dbCommand.ExecuteReader();
if (dbReader.HasRows)
dtResults.Load(dbReader);
string theSum = dtResults.Rows[0]["Total_Source"].ToString();
string theSum1 = dtResults.Rows[0]["Total_Destination"].ToString();
//string theSum2 = dtResults.Rows[0]["Count_Blank"].ToString();
I believe I need to define command text for table B and C (which is incorrect in the above script) but I am unaware how to do.
Appreciate any help!
Store the counts in variables and return those in a select - make this your SQL statement:
DECLARE #total_Source AS INT;
DECLARE #total_Destination AS INT;
DECLARE #total_Blank AS INT;
SELECT #total_Source=Count(*) FROM [dbo].A;
SELECT #total_Destination=Count(*) FROM [dbo].B;
SELECT #total_Blank=Count(*) FROM [dbo].C WHERE ColumnA = ''";
SELECT #total_Source AS Total_Source, #total_Destination AS Total_Destination, #total_Blank AS Total_Blank
I haven't tried it, but I think that if CommandText is a string property, you are overwritting it on each sentence you use the = operator.
You could try this:
//...
OleDbCommand dbCommand = dbConnection.CreateCommand();
dbCommand.CommandType = CommandType.Text;
var sb = new System.Text.StringBuilder();
sb.Append("select count(*) as Total_Source from [dbo].A;"); // Notice semicolon at the end of the string.
sb.Append("select count(*) as Total_Destination from [dbo].B;");
sb.Append("select count(*) as Total_Blank from [dbo].C where ColumnA = '';");
dbCommand.CommandText = sb.ToString();
OleDbDataReader dbReader = dbCommand.ExecuteReader();
//...
Related
I get this error:
There is already an open DataReader associated with this Command which must be closed first
This is my code :
String sql_get_completed_tasks = "select * from tasks where Ending_date is not null order by Ending_date asc";
SqlCommand command_get_completed_tasks_ = new SqlCommand(sql_get_completed_tasks, cn);
SqlDataReader reader = command_get_completed_tasks_.ExecuteReader();
while (reader.Read())
{
String sql_insert_completed_tasks_toTheNewTable = "insert into history_of_tasks_achievements values ("+
reader[1] +" , N'"+ reader[2]+"' , #image , N'"+ reader[4] +"' , N'"+reader[5]+"' , N'"+ reader[6]+"' , "+
reader[7] +" , N'"+reader[8]+"' , N'"+reader[9] +"' , "+reader[10]+" , #start_date , #end_date , "+reader[13]+
")";
SqlCommand com_insert_completed_tasks_toTheNewTable = new SqlCommand(sql_insert_completed_tasks_toTheNewTable, cn);
com_insert_completed_tasks_toTheNewTable.Parameters.Add(new SqlParameter("#image", reader[3]));
com_insert_completed_tasks_toTheNewTable.Parameters.Add(new SqlParameter("#start_date", reader[11]));
com_insert_completed_tasks_toTheNewTable.Parameters.Add(new SqlParameter("#end_date", reader[12]));
com_insert_completed_tasks_toTheNewTable.ExecuteNonQuery();
} // end of while loop
reader.Close();
MessageBox.Show("Done");
To skip this error, can I create pause or close for SqlDataReader, then re-open from the break values? What is the best solution?
That should really just be 1 statement, there is no need to iterate over the results from the select just to push them back to the same database using an insert.
const string sqlInsert =
#"INSERT INTO [history_of_tasks_achievements] (col1, col2, col3, ...)
SELECT col1, col2, col3, ... FROM [tasks] WHERE [Ending_date] IS NOT NULL ORDER BY [Ending_date] ASC";
using(var con = new SqlConnection("connection string here"))
using(var command = new SqlCommand(sqlInsert, con))
{
con.Open();
var inserted = command.ExecuteNonQuery();
}
Be sure to align the columns between the SELECT and the INSERT so they match.
In this case you can use the using statement.
// set up connection, command
using (var reader = command_get_completed_tasks_.ExecuteReader())
{
// do the reader stuff
reader.Close();
}
// Done
I tried to do begin transaction on SQL Server, but it returns an error that I can't figure out what the real problem is. So here is some of my code I tried.
This is the error:
Code:
SqlConnection connection = new SqlConnection("Data Source=LOCALHOST\\SQLEXPRESS;Initial Catalog=tempdb;Integrated Security=SSPI;User ID = xxxx; Password=xxx;");
DateTime dt = dateTimePicker1.Value.Date;
dt = dt.AddDays(60);
string selectQuery = "BEGIN TRANSACTION UPDATE tester SET
test_ad=#dateTimePicker1, test_ud=#dt, test_pd=#dt WHERE
test_name=#textBox1;INSERT INTO records(testr_status, testr_name, testr_ad,
testr_ud, testr_pd, apte_name)VALUES(#testr_status, testr_name = #comboBox1,
testr_ad = #dateTimePicker1, testr_ud = #dt, testr_pd = #dt COMMIT";
connection.Open();
SqlCommand command = new SqlCommand(selectQuery, connection);
command.Parameters.AddWithValue("#dateTimePicker1",this.dateTimePicker1.Value.Date);
command.Parameters.AddWithValue("#textBox1", this.textBox1.Text);
command.Parameters.AddWithValue("#comboBox1",this.comboBox1.SelectedItem);
command.Parameters.AddWithValue("#testr_status",SqlDbType.VarChar);
command.Parameters.AddWithValue("#dt", dt);
int iResult = command.ExecuteNonQuery();
if (iResult > 0)
MessageBox.Show("Successfully saved ", "Error",MessageBoxButtons.OK, MessageBoxIcon.Information);
else
MessageBox.Show("Record not saved ", "Error",MessageBoxButtons.OK, MessageBoxIcon.Error);
command.ExecuteNonQuery();
connection.Dispose();
command.Dispose();
Try cleaning up a bit your query or paste it on SSMS and declare your parameters and you will figure out what is wrong.
In your case your INSERT statement has some errors.
This is not valid syntax VALUES (test_name = #combobox1) instead you only pass the parameter VALUES (#combobox1)
There are more columns in the INSERT statement than values specified in the VALUES clause, you are not providing a value for apte_name. In the c# code you will need to add that parameter too.
You are missing the closing parenthesis for the VALUES clause
You should end up with something like this (not tested)
string selectQuery =
#"BEGIN TRANSACTION
UPDATE tester SET
test_ad = #dateTimePicker1,
test_ud = #dt,
test_pd = #dt
WHERE test_name = #textBox1;
INSERT INTO records
(
testr_status,
testr_name,
testr_ad,
testr_ud,
testr_pd,
apte_name
)
VALUES
(
#testr_status,
#comboBox1,
#dateTimePicker1,
#dt,
#dt,
#apte_name
);
COMMIT";
The actual problem is, that is one big, invalid SQL statement. Use the semi-colon to separate statements, like so:
"BEGIN TRANSACTION;
INSERT ...;
UPDATE ...;
ETC ...;
COMMIT;"
That said, don't embed transaction statements in a query string. Do what Oliver suggests in another answer.
You can use SqlTransaction
using (SqlConnection conn = new SqlConnection("Connection String"))
{
conn.Open();
SqlTransaction trans;
trans = conn.BeginTransaction();
string selectQuery = "your sql query";
SqlCommand command = new SqlCommand(selectQuery, connection);
int iResult = command.ExecuteNonQuery();
if (iResult > 0)
{
trans.Commit();
}else{
trans.Rollback();
}
conn.Close();
}
Use a formatted string for your select query by using # and the syntax in the value block in not accurate.
string selectQuery = #"
BEGIN TRANSACTION
UPDATE tester SET test_ad = #dateTimePicker1, test_ud = #dt, test_pd = #dt WHERE test_name = #textBox1;
INSERT INTO records(testr_status, testr_name, testr_ad, testr_ud, testr_pd, apte_name) VALUES(#testr_status, #comboBox1, #dateTimePicker1, #dt, #dt);
COMMIT";
I can use this loop to give me list of names:
string commandText = #"SELECT ....;";
string connectionString = ConfigurationSettings.AppSettings["connectionString"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
try
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
DataTable dt = new DataTable();
dt.Load(reader);
for (int i = dt.Rows.Count - 1; i >= 0; i--)
{
SqlCommand addresscommand = new SqlCommand(address, connection);
addresscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader addressreader = command.ExecuteReader();
string address = addressreader.GetString(0);
}
}
}
catch (Exception ex)
{
}
}
so the dt.Rows[i][0].ToString() is the name I need to add to all my different sql commands. So inside that for loop I will get each value from executing each sql command, one by one:
SqlCommand addresscommand = new SqlCommand(address, connection);
addresscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader addressreader = addresscommand.ExecuteReader();
string comaddress = addressreader.GetString(0);
SqlCommand keyProcessescommand = new SqlCommand(keyProcesses, connection);
keyProcessescommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader keyProcessesreader = keyProcessescommand.ExecuteReader();
string comkeyProcesses = keyProcessesreader.GetString(0);
SqlCommand standardscommand = new SqlCommand(standards, connection);
standardscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader standardsreader = standardscommand.ExecuteReader();
string comstandards = standardsreader.GetString(0);
Where the command string determined by:
string address = #"SELECT address FROM Companies where companyName = #companyName";
string keyProcesses = #" SELECT distinct STUFF((SELECT ', '+ cn.name from WMCCMCategories cn
INNER JOIN CategorySets uc ON uc.categoryId = cn.categoryID
INNER JOIN KeyProcesses u ON u.categorySetId = uc.setId
INNER JOIN Companies c ON c.companyId = u.companyId
WHERE c.companyName = #companyName
ORDER BY cn.name
FOR XML PATH('')), 1, 1, '') AS listStr
FROM WMCCMCategories cnn Group by cnn.name";
string standards = #" SELECT cn.name from WMCCMCategories cn
INNER JOIN CategorySets uc ON uc.categoryId = cn.categoryID
INNER JOIN Companies c ON c.standards = uc.setId
WHERE c.companyName = #companyName";
Can I execute multiple sql commands like above? How is the best way to do that ?
One way you can solve this through JOIN in SQL. However, it may not be right thing to do if it is not representing same columns.
Now in terms of using multiple select in one command. Yes, you can use SqlDataReader with NextResult()
Please see this link:
http://csharp.net-informations.com/data-providers/csharp-multiple-resultsets.htm
I have two tables, one containing names, and one containing rates and other data that is lined to each name. After I insert a new name into table A, I want to get the newly auto generated PK to now use to insert into my other table B with rates.
How can I do this? I read about scope_identity online but I'm not sure how to use it.
This is what I have so far:
SqlConnection con = new SqlConnection(pubvar.x);
SqlCommand command = con.CreateCommand();
command.CommandText ="Insert into A values('" +Name + "')";
SqlCommand command2 = con.CreateCommand();
command2.CommandText = "Insert into B values(....)";
SELECT SCOPE_IDENTITY();
con.Open();
command.ExecuteNonQuery();
con.Close();
Considering the case you've described, I don't see any need to return the identity from the database. You can simply issue both statements in one command:
using (var cnx = new SqlConnection(pubvar.x))
using (var cmd = new SqlCommand
{
Connection = cnx,
CommandText = #"
insert into A (Name) values (#name)
insert into B (A_ID, Rate) values (scope_identity(), #rate)
",
Parameters =
{
new SqlParameter("#name", name),
new SqlParameter("#rate", .5m) //sample rate
}
})
{
cnx.Open();
cmd.ExecuteNonQuery();
}
i am new to programming. Learning C# and using
visual studio
i made a file with two text boxes. the content of these text boxes
are transferred to another file using javascript
listfile
<script type="text/javascript">
function RunAjax1(custId) {
var custId = document.getElementById("customerId").value;
//var custName = document.getElementById("customerName").value;
jQuery.ajax(
{
url: "CustActions.aspx?id=" + custId +"&custName="+customerName,
type: "GET"
}
).done(function (responseText) {
jQuery("#display").html(responseText)
});
}
</script>
i want to use an if statement before an sql command in order to use one
or the two variables (whichever is not null).
The customerid is integer, while the customerName is a string.
The code is as follows:
actionfile
<% SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connectionString"].ToString());
string cmdText = #"SELECT * FROM Customers where id= #_id";
SqlCommand cmd = new SqlCommand(cmdText, con);
cmd.Parameters.Add("_id", SqlDbType.Int).Value = Convert.ToInt16(Request["id"].ToString());
cmd.Parameters.Add("custName_",SqlDbType.VarChar).Value=Convert.ToChar(Request["custName"].ToString());
DataTable dt = new DataTable();
con.Open();
dt.Load(cmd.ExecuteReader());
con.Close();
foreach (DataRow dr in dt.Rows)
{
Response.Write(string.Format(#"<tr>
<td>{0}</td>
<td>{1}</td>
That is i want a statement like the one that follows
if (_id is Notnull)
{
string cmdText = #"SELECT * FROM Customers where id= #_id";
}
else
{
string cmdText = #"SELECT * FROM Customers where customerName= #custName_";
}
plus variable declaration to the actionfile
Thanks
<% SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connectionString"].ToString());
string cmdText = _id != null
? #"SELECT * FROM Customers where id= #_id"
: #"SELECT * FROM Customers where customerName= #custName_";
SqlCommand cmd = new SqlCommand(cmdText, con);
cmd.Parameters.Add("_id", SqlDbType.Int).Value = Convert.ToInt16(Request["id"].ToString());
cmd.Parameters.Add("custName_",SqlDbType.VarChar).Value=Convert.ToChar(Request["custName"].ToString());
DataTable dt = new DataTable();
con.Open();
dt.Load(cmd.ExecuteReader());
con.Close();
Is this what you want? However its not recommended to put so much code into your aspx files.
its better to put make your code accept 2 parameters and then have the stored procedure handle the nulls and it have the if statement
like this
Create proc dosomething
(
-- initialized the values to null if no value is passed in
#id tinyint = NULL
#CustomerName varchar 100 = NULL
)
BEGIN
if #tinyint is NULL and CustomerName is not null
SELECT * FROM Customers where id= #id ";
END
BEGIN
if #CustomerName is NULL and #tinyint is NOT NULL
SELECT * FROM Customers where customerName= #Customername";
END
BEGIN
if #CustomerName is NULL NOT and #tinyint is NOT NULL
SELECT * FROM Customers where (customerName= #Customername and id = #id) ";
END