I'm first time for C#, Now I try to insert data to oracle db from variable. But I got this error. I don't know what point in this source code .
public class Foo
{
public string PLANTCODE { get; set; }
public string LOCATIONCODE { get; set; }
public string LOCATIONNAME { get; set; }
public string LOCATIONSTATUS { get; set; }
public string DEPARTMENTCODE { get; set; }
public string DEPARTMENTNAME { get; set; }
// public DateTime LASTUPDATED { get; set; }
// public OracleDbType OracleDbType { get; set; }
}
public List<Foo> GetData()
{
List<Foo> dataList = new List<Foo>();
string connectionString = "Data Source=xxx; Initial Catalog=xxx;Integrated Security = false; User ID=xxx;Password=xxx";
string selectStatement = "SELECT PLANTCODE,LOCATIONCODE,LOCATIONNAME,LOCATIONSTATUS,DEPARTMENTCODE,DEPARTMENTNAME from V_Location";
using (var con = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(selectStatement, con))
{
con.Open();
using (var reader = cmd.ExecuteReader())
{ if (reader.Read())
{
dataList.Add(new Foo
{
PLANTCODE = reader.GetString(0),
LOCATIONCODE = reader.GetString(1),
LOCATIONNAME = reader.GetString(2),
LOCATIONSTATUS = reader.GetString(3),
DEPARTMENTCODE = reader.GetString(4),
DEPARTMENTNAME = reader.GetString(5),
});
}
}
}
}
return dataList;
}
public void InsertData()
{
string connectionString = "Provider=MSDAORA;Data Source=ORCL;Persist Security Info=True;User ID=xxx;Password=xxx;Unicode=True";
string insertStatment = "INSERT INTO xxx.BTH_V_LOCATION (PLANTCODE, LOCATIONCODE, LOCATIONNAME, LOCATIONSTATUS, DEPARTMENTCODE, DEPARTMENTNAME) VALUES (:PLANTCODE, :LOCATIONCODE, :LOCATIONNAME, :LOCATIONSTATUS, :DEPARTMENTCODE, :DEPARTMENTNAME)";
List<Foo> dataList = GetData();
if (dataList.Count > 0)
{
using (OleDbConnection con = new OleDbConnection(connectionString))
{
using (OleDbCommand cmd = new OleDbCommand(insertStatment, con))
{
con.Open();
foreach (var items in dataList)
{
cmd.Parameters.Clear();
cmd.Parameters.Add("PLANTCODE", OleDbType.VarChar).Value = items.PLANTCODE;
cmd.Parameters.Add("LOCATIONCODE", OleDbType.VarChar).Value = items.LOCATIONCODE;
cmd.Parameters.Add("LOCATIONNAME", OleDbType.VarChar).Value = items.LOCATIONNAME;
cmd.Parameters.Add("LOCATIONSTATUS", OleDbType.VarChar).Value = items.LOCATIONSTATUS;
cmd.Parameters.Add("DEPARTMENTCODE", OleDbType.VarChar).Value = items.DEPARTMENTCODE;
cmd.Parameters.Add("DEPARTMENTNAME", OleDbType.VarChar).Value = items.DEPARTMENTNAME;
}
cmd.ExecuteNonQuery();
}
}
}
}
private void button1_Click_1(object sender, EventArgs e)
{
InsertData();
}
}
}
This source code get select data from sql server first. After that keep data in variable for insert to oracle. Now I try to insert without variable then can insert data. but if I change to insert by variable but can't insert and get this error
ORA-01008: not all variables bound error" on "cmd.ExecuteNonQuery();
Move cmd.Parameters.clear(); outside the loop.
Seems to be clearing every time.
Thank you so much for your answer, But I try to move cmd.Parameters.clear(); , I still got same error.
using (OleDbConnection con = new OleDbConnection(connectionString)) //OleDbConnection
{
using (OleDbCommand cmd = new OleDbCommand(insertStatment, con)) //OleDbCommand
{
con.Open();
foreach (var items in dataList)
{
cmd.Parameters.Add("PLANTCODE", OleDbType.VarChar).Value = items.PLANTCODE;
cmd.Parameters.Add("LOCATIONCODE", OleDbType.VarChar).Value = items.LOCATIONCODE;
cmd.Parameters.Add("LOCATIONNAME", OleDbType.VarChar).Value = items.LOCATIONNAME;
cmd.Parameters.Add("LOCATIONSTATUS", OleDbType.VarChar).Value = items.LOCATIONSTATUS;
cmd.Parameters.Add("DEPARTMENTCODE", OleDbType.VarChar).Value = items.DEPARTMENTCODE;
cmd.Parameters.Add("DEPARTMENTNAME", OleDbType.VarChar).Value = items.DEPARTMENTNAME;
}
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
and I try to swap "cmd.ExecuteNonQuery();" and "cmd.Parameters.Clear();" but same result.
Now I can fixed this problem, I change paramater name to "?"
string insertStatment = "INSERT INTO xxx.BTH_V_LOCATION (PLANTCODE, LOCATIONCODE, LOCATIONNAME, LOCATIONSTATUS, DEPARTMENTCODE, DEPARTMENTNAME) VALUES (?,?,?,?,?,?)";
List<Foo> dataList = GetData();
if (dataList.Count > 0)
{
using (OleDbConnection con2 = new OleDbConnection(connectionString)) //OleDbConnection
{
using (OleDbCommand cmd2 = new OleDbCommand(insertStatment, con2)) //OleDbCommand
{
con2.Open();
cmd2.Parameters.Clear();
foreach (var items in dataList)
{
cmd2.Parameters.Add("?", OleDbType.VarChar).Value = items.PLANTCODE;
cmd2.Parameters.Add("?", OleDbType.VarChar).Value = items.LOCATIONCODE;
cmd2.Parameters.Add("?", OleDbType.VarChar).Value = items.LOCATIONNAME;
cmd2.Parameters.Add("?", OleDbType.VarChar).Value = items.LOCATIONSTATUS;
cmd2.Parameters.Add("?", OleDbType.VarChar).Value = items.DEPARTMENTCODE;
cmd2.Parameters.Add("?", OleDbType.VarChar).Value = items.DEPARTMENTNAME;
//cmd2.ExecuteNonQuery();
//cmd2.Parameters.Clear();
}
cmd2.ExecuteNonQuery();
//cmd2.Parameters.Clear();
}
}
}
I think you need to use # instead of : for the parameters. And you need to execute within the loop and clear params after the execution.
string insertStatment = "INSERT INTO xxx.BTH_V_LOCATION (PLANTCODE, LOCATIONCODE, LOCATIONNAME, LOCATIONSTATUS, DEPARTMENTCODE, DEPARTMENTNAME) VALUES (#PLANTCODE, #LOCATIONCODE, #LOCATIONNAME, #LOCATIONSTATUS, #DEPARTMENTCODE, #DEPARTMENTNAME)";
List<Foo> dataList = GetData();
if (dataList.Count > 0)
{
using (OleDbConnection con = new OleDbConnection(connectionString))
{
using (OleDbCommand cmd = new OleDbCommand(insertStatment, con))
{
con.Open();
foreach (var items in dataList)
{
cmd.Parameters.AddRange(new OleDbParameter[]
{
new OleDbParameter("#PLANTCODE", items.PLANTCODE),
new OleDbParameter("#LOCATIONCODE", items.LOCATIONCODE),
new OleDbParameter("#LOCATIONNAME", items.LOCATIONNAME),
new OleDbParameter("#LOCATIONSTATUS", items.LOCATIONSTATUS),
new OleDbParameter("#DEPARTMENTCODE", items.DEPARTMENTCODE),
new OleDbParameter("#DEPARTMENTNAME", items.DEPARTMENTNAME),
});
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
}
}
I'm trying to get two column details like this way:
public string GetData()
{
using (SqlConnection con = new SqlConnection(this.Connection))
{
con.Open();
SqlCommand command = new SqlCommand("Select TITTLE,VALUE from T_PROJECTS ", con);
// int result = command.ExecuteNonQuery();
using (SqlDataReader reader = command.ExecuteReader())
{
reader.Read();
return reader["TITTLE,VALUE"]?.ToString();
}
}
}
How can I do this?
You need to have a custom class of columns that you want to retrieve, for example,
public class Project
{
public int Title { get; set; }
public string Value { get; set; }
}
and then like this,
public Project GetData()
{
using (SqlConnection con = new SqlConnection(this.Connection))
{
con.Open();
SqlCommand command = new SqlCommand("Select TITTLE,VALUE from T_PROJECTS ", con);
Project proObj = new Project();
using (SqlDataReader reader = command.ExecuteReader())
{
reader.Read();
proObj.Title = reader["TITTLE"].ToString();
proObj.Value = reader["VALUE"].ToString();
}
}
return proObj;
}
You could also return a Tuple although I feel a custom class is a much better solution. -> https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx
public IEnumerable<Tuple<string,string>> GetData()
{
List<Tuple<string,string> results = new List<Tuple<string,string>>();
using (SqlConnection con = new SqlConnection(this.Connection))
{
con.Open();
SqlCommand command = new SqlCommand("Select TITTLE,VALUE from T_PROJECTS ", con);
using (SqlDataReader reader = command.ExecuteReader())
{
while(reader.Read())
results.add(new Tuple<string,string>(reader["TITLE"].ToString(),reader["VALUE"].ToString()));
}
return results;
}
}
Im trying to to get all of my table records using webservice. I tried this :
public class Student
{
public int id;
public string name;
public string grade;
}
[WebMethod]
public Student[] getall()
{
Student objStd = new Student();
Student[] stds = new Student[400];
SqlConnection conn;
conn = Class1.ConnectionManager.GetConnection();
conn.Open();
SqlCommand newCmd = conn.CreateCommand();
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "select * from dbo.tblUser";
SqlDataReader sdr = newCmd.ExecuteReader();
for (int runs = 0; sdr.Read(); runs++)
{
objStd.id = Int32.Parse(sdr["Id"].ToString());
objStd.name = sdr["name"].ToString();
objStd.grade = sdr["grade"].ToString();
stds[runs] = objStd;
}
conn.Close();
sdr.Close();
return stds;
}
but the result of this is like this:
<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfStudent xmlns="http://tempuri.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-<Student>
<id>8</id>
<name>hhhhh</name>
<grade>76</grade>
</Student>
-<Student>
<id>8</id>
<name>hhhhh</name>
<grade>76</grade>
</Student>
-<Student>
<id>8</id>
<name>hhhhh</name>
<grade>76</grade>
</Student>
-<Student>
<id>8</id>
<name>hhhhh</name>
<grade>76</grade>
</Student>
....
this will return only the last record again and again, why?
what should I correct in my code?
Make a List add to it and return, now you are returning only the last object.
Create the Student Object instance inside the For Loop
List<Student> stds = new List<Student>();
for (int runs = 0; sdr.Read(); runs++)
{
Student objStd = new Student();
objStd.id = Int32.Parse(sdr["Id"].ToString());
objStd.name = sdr["name"].ToString();
objStd.grade = sdr["grade"].ToString();
stds.Add(objStd);
}
Create objStudent inside the loop so you don't keep updating the same student
[WebMethod]
public Student[] getall()
{
Student[] stds = new Student[400];
SqlConnection conn;
conn = Class1.ConnectionManager.GetConnection();
conn.Open();
SqlCommand newCmd = conn.CreateCommand();
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "select * from dbo.tblUser";
SqlDataReader sdr = newCmd.ExecuteReader();
for (int runs = 0; sdr.Read(); runs++)
{
Student objStd = new Student();
objStd.id = Int32.Parse(sdr["Id"].ToString());
objStd.name = sdr["name"].ToString();
objStd.grade = sdr["grade"].ToString();
stds[runs] = objStd;
}
conn.Close();
sdr.Close();
return stds;
}
If your count of student is dynamic use list instead of array with static lenght. Also you must create student object when you read new record from Reader.
[WebMethod]
public Student[] getall()
{
List<Student> studentList=new List<Student>();
SqlConnection conn;
conn = Class1.ConnectionManager.GetConnection();
conn.Open();
SqlCommand newCmd = conn.CreateCommand();
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "select * from dbo.tblUser";
SqlDataReader sdr = newCmd.ExecuteReader();
while(sdr.Read()){
Student student= new Student();
student.id = Int32.Parse(sdr["Id"].ToString());
student.name = sdr["name"].ToString();
student.grade = sdr["grade"].ToString();
studentList.Add(student);
}
conn.Close();
sdr.Close();
return studentList.ToArray();
}
this is how I try to print something worthwhile for my site using my class, When I try to write my class will not find it at all.
I can not find my worth to return something worthwhile for my user.
the problem is that it can not find at all class.
My class:
public class AbonnementsId
{
public int indhold { get; set; }
}
public AbonnementsId HentAbonnementsId()
{
AbonnementsId AbonnementsidReturn = new AbonnementsId();
AbonnementsidReturn.indhold = 0;
SqlConnection conn1 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());
SqlCommand cmd1 = conn1.CreateCommand();
cmd1.Connection = conn1;
int brugerid = Convert.ToInt32(HttpContext.Current.Session["id"]);
cmd1.CommandText = #"SELECT abonnementsid from brugere WHERE id = #id";
cmd1.Parameters.AddWithValue("#id", brugerid);
conn1.Open();
SqlDataReader readerBrugerA = cmd1.ExecuteReader();
if (readerBrugerA.Read())
{
AbonnementsidReturn.indhold = Convert.ToInt32(readerBrugerA["abonnementsid"]);
}
conn1.Close();
return AbonnementsidReturn;
}
Here is how I write my class out when I need it for my content.
if (Session["AbonnementsId"] != null)
{
_subscriptionId = long.Parse(Session["AbonnementsId"].ToString());
}
else
{
//when I need to print my class do I like it here
_subscriptionId = AbonnementsidReturn.indhold();
}
I'm totally shooting in the dark here:
public static class AbonnementsId
{
public static int GetAbonnementsId()
{
int abonnementsid;
string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
using(var conn = new SqlConnection(connectionString))
{
int brugerid = Convert.ToInt32(HttpContext.Current.Session["id"]);
SqlCommand cmd1 = conn.CreateCommand();
cmd1.Connection = conn;
cmd1.CommandText = #"SELECT abonnementsid from brugere WHERE id = #id";
cmd1.Parameters.AddWithValue("#id", brugerid);
conn.Open();
SqlDataReader readerBrugerA = cmd1.ExecuteReader();
if (readerBrugerA.Read())
abonnementsid = Convert.ToInt32(readerBrugerA["abonnementsid"]);
conn.Close();
}
return abonnementsid;
}
}
You can then call this in your code:
if (Session["AbonnementsId"] != null)
{
_subscriptionId = long.Parse(Session["AbonnementsId"].ToString());
}
else
{
//when I need to print my class do I like it here
_subscriptionId = AbonnementsId.GetAbonnementsId();
}
I have a method (with WebMethod attribute), I define a transaction, in my method and in my transaction I call 2 stored procedures, first one is GetAllBook :
select *
from Book_TBL
where IsActive = 'True'
and second one is updateBook :
update Book_TBL
set IsActive = 'False'
where IsActive = 'True'
and my method :
public struct BOOK
{
public string BOOK_NAME;
public string BOOK_DESC;
}
[WebMethod]
public static List<BOOK> GetMyBooks()
{
using (TransactionScope _transactionScope = new TransactionScope(TransactionScopeOption.Required))
{
string _connString = "Data Source=.;Initial Catalog=BookStore;Integrated Security=True";
SqlConnection _conn = new SqlConnection(_connString);
_conn.Open();
SqlCommand _com = new SqlCommand();
_com.CommandType = System.Data.CommandType.StoredProcedure;
_com.CommandText = "GetAllBook";
_com.Connection = _conn;
SqlDataAdapter bookdataAdapter = new SqlDataAdapter(_com);
DataSet bookDS = new DataSet();
bookdataAdapter.Fill(bookDS, "Book_TBL");
List<BOOK> bookList = new List<BOOK>();
_conn.Close();
BOOK book;
foreach (DataRow dr in bookDS.Tables["Book_TBL"].Rows)
{
book = new BOOK();
book.BOOK_NAME = dr["book_name"].ToString();
book.BOOK_DESC = dr["book_desc"].ToString();
bookList.Add(book);
}
SqlCommand updateCommand= new SqlCommand();
_conn.Open();
updateCommand.CommandText = "updateBook";
updateCommand.CommandType = System.Data.CommandType.StoredProcedure;
updateCommand.Connection = _conn;
updateCommand.ExecuteNonQuery();
_conn.Close();
return bookList;
}
}
When I run the project myMethod gives me the list of books which have IsActive = True but it did not update my table! What is the problem?
You have to call TransactionScope.Complete, the equivalent of a commit. Without it, the using blocks disposes it and that's equivalent to a rollback.
I don't knoe what are you really want to do with a such deeply nested method but you should put everything in place first:
public class Book
{
public string Name { get; set; }
public string Description { get; set; }
}
public static List<Book> GetMyBooks()
{
var bookList = new List<Book>();
using (var transactionScope = new TransactionScope(TransactionScopeOption.Required))
{
const string connString = "Data Source=.;Initial Catalog=BookStore;Integrated Security=True";
using (var conn = new SqlConnection(connString))
{
using (var com = new SqlCommand())
{
com.CommandType = CommandType.StoredProcedure;
com.CommandText = "GetAllBook";
com.Connection = conn;
using (var bookdataAdapter = new SqlDataAdapter(com))
{
using (var bookDataSet = new DataSet())
{
bookdataAdapter.Fill(bookDataSet, "Book_TBL");
foreach (DataRow dr in bookDataSet.Tables["Book_TBL"].Rows)
{
bookList.Add(new Book
{
Name = dr["book_name"].ToString(),
Description = dr["book_desc"].ToString()
});
}
using (var updateCommand = new SqlCommand())
{
updateCommand.CommandText = "updateBook";
updateCommand.CommandType = CommandType.StoredProcedure;
updateCommand.Connection = conn;
updateCommand.ExecuteNonQuery();
}
}
}
}
}
transactionScope.Complete();
return bookList;
}
}
And as mentioned the other you have to manually commit the transaction.
You should be using the class SqlTransaction like this:
using (SqlConnection cn = new SqlConnection())
{
cn.Open();
using (SqlTransaction tr = cn.BeginTransaction())
{
//some code
tr.Commit();
}
}