C# ORA-01008: not all variables bound error - c#

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();
}
}
}
}

Related

How to dynamically Add rows into Table?

I have a Contact Form where the user can add 1 or more (max 5) contacts. Once the user clicks save, the program needs to check the number of contacts submitted and insert into the Contacts_Table accordingly as separate rows. For example, if the user provides 3 contacts, 3 rows should be inserted into the database. The problem here is am able to achieve the goal, but am trying to reduce the number of code lines.
Here is the sample code:
string internalContact = "insert into InternalContact("
+ "Phone, FirstName, Surname)"
+ "values (#Phone, #FirstName, #Surname)";
using (OleDbConnection conn1 = new OleDbConnection(ConnString))
{
using (OleDbCommand cmd1 = new OleDbCommand(internalContact, conn1))
{
conn1.Open();
cmd1.CommandType = CommandType.Text;
cmd1.Parameters.Add("FirstName", OleDbType.VarChar).Value = TextBox34.Text;
cmd1.Parameters.Add("Surname", OleDbType.VarChar).Value = TextBox42.Text;
cmd1.Parameters.Add("Phone", OleDbType.VarChar).Value = TextBox45.Text;
cmd1.ExecuteNonQuery();
if (TextBox64.Text != "")
{
cmd1.Parameters.Clear();
cmd1.Parameters.Add("FirstName", OleDbType.VarChar).Value = TextBox64.Text;
cmd1.Parameters.Add("Surname", OleDbType.VarChar).Value = TextBox65.Text;
cmd1.Parameters.Add("Phone", OleDbType.VarChar).Value = TextBox69.Text;
cmd1.ExecuteNonQuery();
}
conn1.Close();
}
}
I would create a struct list and pass all contact info to the method.
struct contactInfo
{
public string FirstName;
public string Surname;
public string Phone;
}
private void insertContacts (List<contactInfo> pList)
{
using (OleDbConnection conn1 = new OleDbConnection(ConnString))
{
conn1.Open();
foreach (contactInfo info in pList)
{
using (OleDbCommand cmd1 = new OleDbCommand(internalContact, conn1))
{
cmd1.CommandType = CommandType.Text;
cmd1.Parameters.Add("FirstName", OleDbType.VarChar).Value = info.FirstName;
cmd1.Parameters.Add("Surname", OleDbType.VarChar).Value = info.Surname;
cmd1.Parameters.Add("Phone", OleDbType.VarChar).Value = info.Phone;
cmd1.ExecuteNonQuery();
}
}
conn1.Close();
}
}

How to retrieve multiple column from SQL database?

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;
}
}

Unable to show extracted data from the table in fiddler

I have written the following code to extract all records from the table in the SQL server. There is no error in the code but when I run it in fiddler, I am getting null objects.
[HttpGet]
public List<Student> Get()
{
SqlDataReader reader = null;
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = #"Data Source=PALLAVI-PC\SQLEXPRESS;Initial Catalog=StudentDB;Integrated Security=True;MultipleActiveResultSets=True;";
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = "Select * from Tbl_Students;";
sqlCmd.Connection = myConnection;
myConnection.Open();
reader = sqlCmd.ExecuteReader();
int rowCount = 0;
while (reader.Read())
{
rowCount++;
}
Student[] student = new Student[rowCount];
for(int i=0;i<rowCount;i++)
{
student[i] = new Student();
}
int j = 0;
while (reader.Read())
{
// student[j] = new Student();
student[j].Roll_Number = Convert.ToInt32(reader.GetValue(0));
student[j].FirstName = reader.GetValue(1).ToString();
student[j].LastName = reader.GetValue(2).ToString();
student[j].Class = Convert.ToInt32(reader.GetValue(3));
student[j].Gender = reader.GetValue(4).ToString();
j++;
}
return student.ToList();
myConnection.Close();
}
I have 5 records in the table. I am able to get 5 json objects but without the content.
Attaching the image from Fiddler:
Student.cs
namespace WebAPIDemo.Models
{
public class Student
{
public int Roll_Number { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Class { get; set; }
public string Gender { get; set; }
}
}
Try this, without taking count of records. I'm not using the array, I have created new instance of student for each record.
public static List<Student> GetData()
{
List<Student> lstStudent = new List<Student>();
using (SqlConnection con = new SqlConnection(#"Data Source=PALLAVI-PC\SQLEXPRESS;Initial Catalog=StudentDB;Integrated Security=True;MultipleActiveResultSets=True;"))
{
using (SqlCommand cmd = new SqlCommand("Select * from Tbl_Students;", con))
{
cmd.CommandType = CommandType.Text;
if (con.State == ConnectionState.Closed)
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
Student student =new Student();
student.Roll_Number = Convert.ToInt32(reader.GetValue(0));
student.FirstName = reader.GetValue(1).ToString();
student.LastName = reader.GetValue(2).ToString();
student.Class = Convert.ToInt32(reader.GetValue(3));
student.Gender = reader.GetValue(4).ToString();
lstStudent.Add(student);
}
}
}
return lstStudent;
}
your first while(reader.Read()) is the actual reader object with data. DataReader allows forward only read only access to a data row.The next while loop won't even execute because the Read() is already completed.So you're getting an array of 5 Student objects that are initialized with default values.
Instead of initializing an array of Student populate instances and add to a List<Student> inside the while loop.

my class gives no value back that I can use

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();
}

How to read data in each row and each column from sql table in asp.net using C#?

Sql database is StudentInfo and Table name is Registration
ID----------Name---------------Email---------------------------PhoneNo
1 Munasunghe amilamunasinghe#yahoo.com 0717069425
2 Liyanarachchi hareshliya6#gmail.com 0756706352
protected void Page_Load(object sender, EventArgs e)
{
string query = "select ID, Name, Email, PhoneNo from Registration";
SqlCommand cmd1 = new SqlCommand(query);
DataTable dt1 = GetData(cmd1);
int rowcount = dt1.Rows.Count;
/* I want to read data in each row step by step and assign to variables*/
}
The function GetData is used to get data from the Database.
private DataTable GetData(SqlCommand cmd)
{
DataTable dt = new DataTable();
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
SqlConnection con = new SqlConnection(strConnString);
SqlDataAdapter sda = new SqlDataAdapter();
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
try
{
con.Open();
sda.SelectCommand = cmd;
sda.Fill(dt);
return dt;
}
catch
{
return null;
}
finally
{
con.Close();
sda.Dispose();
con.Dispose();
}
}
ID is Primarykey.
Results should be like(Name,Email,Phone No are variables and 1,2,... are ID value)
Name[1]=Munasunghe
Name[2]=Liyanarachchi
Email[1]=amilamunasinghe#yahoo.com
Email[2]=hareshliya6#gmail.com
Phone No[1]=0717069425
Phone No[2]=0756706352
I would say you firstly create a new class for storing your data (like StudentInfo)
public class StudentInfo
{
public StudentInfo(int ID, string Name, string Email, string PhoneNo)
{
this.ID = ID;
this.Name = Name;
this.Email = Email;
this.PhoneNo = PhoneNo;
}
public int ID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string PhoneNo { get; set; }
}
Then use this function that return's a List of StudentInfo class
public List<StudentInfo> GetData()
{
List<StudentInfo> data = new List<StudentInfo>();
SqlConnection con = new SqlConnection("Your connection string");
SqlCommand command = new SqlCommand("SELECT * FROM [Registration]", con);
con.Open();
SqlDataReader sdr = command.ExecuteReader();
while(sdr.Read())
{
data.Add((int)sdr["ID"], (string)sdr["Name"], (string)sdr["Email"], (string)sdr["PhoneNo"]);
}
con.Close();
return data;
}
Then you use it like this:
List<StudentInfo> info = GetData();
foreach(StudentInfo si in info)
{
Response.Write("<h3>ID is " + si.ID + "</h3><p>StudentName is " + si.Name + "</p>");
}
To update the values do this:
public void SetValue(int StudentID, String NewName, String NewEmail, String NewPhone)
{
SqlConnection con = new SqlConnection("Your connection string");
SqlCommand command = new SqlCommand("UPDATE [Registration] SET [Name]='" + NewName + "', [Email]='" + NewEmail + "', [PhoneNo]='" + NewPhone + "' WHERE [ID]=" + StudentID + "", con);
con.Open();
command.ExecuteNonQuery();
con.close();
}
And I would suggest you to read some articles about sql

Categories

Resources