For some reason I had to store a DataTable variable in a Varbinary column of a SQL Server table, but I get errors.
This is store code:
// Read DataTable to Byte array
DataTable dtgrd = new DataTable();
DataAccess ds = new DataAccess();
DataSet dst = new DataSet();
dst.Tables.Add(dtgrd);
string xmlString = dst.GetXml();
MemoryStream ms = new MemoryStream();
XmlDocument xml = new XmlDocument();
xml.LoadXml(xmlString);
xml.Save(ms);
byte[] xmlBytes = ms.ToArray();
// Store DataTable into database
SqlConnection CN = new SqlConnection(Global.cs);
string str = #"INSERT INTO...... ";
SqlCommand SqlCom = new SqlCommand(str, CN);
SqlCom.Parameters.Add(new SqlParameter("#FKDocInReqID", FKDocInReqID));
SqlCom.Parameters.Add(new SqlParameter("#value", (object)xmlBytes));
SqlCom.Parameters.Add(new SqlParameter("#Data", ReportTitle));
SqlCom.Parameters.Add(new SqlParameter("#DocUploadUser_secuserID", Global.S_UserID));
CN.Open();
decimal id =(decimal) SqlCom.ExecuteScalar();
CN.Close();
The store code has worked correctly and in the database, the columns has the proper bytes.
But the retrieve code does not work:
string s = #"select * from .... where id={0} ";
s = string.Format(s, id);
DataTable dt = new DataTable();
dt = ds.doSelect(s);
using (System.IO.MemoryStream memStream1 = new System.IO.MemoryStream((byte[])dt.Rows[0]["Value"]))
{
dataGridView1.DataSource = FromBytes(memStream1.ToArray());
dataGridView1.Refresh();
dataGridView1.Show();
}
and
static DataTable FromBytes(byte[] arr)
{
using (var ms = new MemoryStream(arr))
{
return (DataTable)new BinaryFormatter().Deserialize(ms);//**ERROR Raised Here**
}
}
static byte[] ToBytes(DataTable table)
{
using (var ms = new MemoryStream())
{
table.RemotingFormat = SerializationFormat.Binary;
new BinaryFormatter().Serialize(ms, table);
return ms.ToArray();
}
}
this error is raised:
error message
The example code on Microsoft's website uses XmlTextReader
static DataTable FromBytes(Stream st)
{
var ds = new DataSet();
using (XmlTextReader xmlReader = new XmlTextReader(st))
{
ds.ReadXml(xmlReader);
}
return ds.Tables[0];
}
I'll leave you to think about the obvious design flaws in storing one table within another.
this is how I figure out this problem maybe help to someone else.
instead of save data into Varbinary field save it to xml in nvarchar(max) and then retrieve it :
//Retrieve Process:
string s = #"select * from .... where id={0} ";
s = string.Format(s, ID);
DataTable dtlist = new DataTable();
DataAccess ds = new DataAccess();
dtlist = ds.doSelect(s);//doselect is function that run select sql command
XmlDocument xml = new XmlDocument();
xml.LoadXml(dtlist.Rows[0]["Data"].ToString());//data is column name that store xml in it
StringReader theReader = new StringReader(xml.InnerXml);
DataSet theDataSet = new DataSet();
theDataSet.ReadXml(theReader);
gridEX1.DataSource = theDataSet.Tables[0];
In my table there is one XML column. I want to fetch the XML data in one textbox and make some corrections and update it:
private void button2_Click(object sender, EventArgs e)
{
con.Open();
string str = "select C1 from TableName where C2='" + txt1.Text+ "'";
SqlCommand cmd1 = new SqlCommand(str, con);
XmlReader xml = cmd1.ExecuteXmlReader();
xml.Read();
txt2.Text = xml.ReadOuterXml();
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.LoadXml(txt2.Text);
}
Now I want to make some changes and update it in my database. When I try to change in textbox it does not work. How can I make changes and update in database? Please help
Update Like this
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "Update TableName set C1 = #C1 where C2 = #C2 ";
command.Parameters.AddWithValue("#C1", Textbox2.Text);
command.Parameters.AddWithValue("#C2", Textbox1.text);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
I have been trying to debug a piece of code and I have been thus far very unsuccessful in doing this.
I keep on getting this error
System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near ')'
and I can't seem to see where the error is.
The code is below, having looked at various answers on this site and looked at the examples. The situation is that I am writing a program that accesses a database and is able to add and save data to that database. It is located on a server - though this is on my laptop.
I have written, re-written and copied the connection string to ensure there are no mistakes in it and even dropped a copy of the string into word and compared it to the one that is in the coding itself but to no avail.
public partial class AddingClients : Form
{
public AddingClients()
{
InitializeComponent();
}
String CompanyName2;
String ClientName2;
String CompanyAddress12;
String CompanyAddress22;
String CompanyAddress32;
String CompanyTown2;
String CompanyPostCode2;
String TelephoneNumber2;
String CompanyEMail2;
String CompanyNotes2;
String ClientReference2;
public SqlConnection con;
public void connection()
{
String connectionstr = #"Data Source=ACER\PATTESTSERVER;Initial Catalog=PatTest;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;";
con = new SqlConnection(connectionstr);
con.Open();
}
private void Finish_Click(object sender, EventArgs e)
{
ClientReference2 = Id.Text;
CompanyName2 = CompanyName.Text;
ClientName2 = ClientName.Text;
CompanyAddress12 = CompanyAddress1.Text;
CompanyAddress22 = CompanyAddress2.Text;
CompanyAddress32 = CompanyAddress3.Text;
CompanyTown2 = CompanyTown.Text;
CompanyPostCode2 = CompanyPostCode.Text;
TelephoneNumber2 = TelephoneNumber.Text;
CompanyEMail2 = CompanyEMail.Text;
CompanyNotes2 = CompanyNotes.Text;
String connectionstr = #"Data Source=ACER\PATTESTSERVER;Initial Catalog=PatTest;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;";
con = new SqlConnection(connectionstr);
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO ClientTable(Id, ClientName, CompanyName, CompanyAddress1, CompanyAddress2, CompanyAddress3, CompanyTown, CompanyPostCode, TelephoneNumber, CompanyEMail, CompanyNotes,) VALUES(#parameter1, #parameter2, #parameter3, #parameter4, #parameter5, #parameter6, #parameter7, #parameter8, #parameter9, #parameter10, #parameter11,)", con);
cmd.Parameters.AddWithValue("#parameter1", ClientReference2);
cmd.Parameters.AddWithValue("#parameter2", ClientName2);
cmd.Parameters.AddWithValue("#parameter3", CompanyName2);
cmd.Parameters.AddWithValue("#parameter4", CompanyAddress12);
cmd.Parameters.AddWithValue("#parameter5", CompanyAddress22);
cmd.Parameters.AddWithValue("#parameter6", CompanyAddress32);
cmd.Parameters.AddWithValue("#parameter7", CompanyTown2);
cmd.Parameters.AddWithValue("#parameter8", CompanyPostCode2);
cmd.Parameters.AddWithValue("#parameter9", TelephoneNumber2);
cmd.Parameters.AddWithValue("#parameter10", CompanyEMail2);
cmd.Parameters.AddWithValue("#parameter11", CompanyNotes2);
cmd.ExecuteNonQuery();
//this method moves to the next screen.
this.Hide();
Asset M1 = new Asset();
M1.Show();
}
private void SaveandNext_Click(object sender, EventArgs e){
ClientReference2 = Id.Text;
CompanyName2 = CompanyName.Text;
ClientName2 = ClientName.Text;
CompanyAddress12 = CompanyAddress1.Text;
CompanyAddress22 = CompanyAddress2.Text;
CompanyAddress32 = CompanyAddress3.Text;
CompanyTown2 = CompanyTown.Text;
CompanyPostCode2 = CompanyPostCode.Text;
TelephoneNumber2 = TelephoneNumber.Text;
CompanyEMail2 = CompanyEMail.Text;
CompanyNotes2 = CompanyNotes.Text;
String connectionstr = #"Data Source=ACER\PATTESTSERVER;Initial Catalog=PatTest;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;";
con = new SqlConnection(connectionstr);
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO ClientTable(Id, ClientName, CompanyName, CompanyAddress1, CompanyAddress2, CompanyAddress3, CompanyTown, CompanyPostCode, TelephoneNumber, CompanyEMail, CompanyNotes,) VALUES(#parameter1, #parameter2, #parameter3, #parameter4, #parameter5, #parameter6, #parameter7, #parameter8, #parameter9, #parameter10, #parameter11,)", con);
cmd.Parameters.AddWithValue("#parameter1", ClientReference2);
cmd.Parameters.AddWithValue("#parameter2", ClientName2);
cmd.Parameters.AddWithValue("#parameter3", CompanyName2);
cmd.Parameters.AddWithValue("#parameter4", CompanyAddress12);
cmd.Parameters.AddWithValue("#parameter5", CompanyAddress22);
cmd.Parameters.AddWithValue("#parameter6", CompanyAddress32);
cmd.Parameters.AddWithValue("#parameter7", CompanyTown2);
cmd.Parameters.AddWithValue("#parameter8", CompanyPostCode2);
cmd.Parameters.AddWithValue("#parameter9", TelephoneNumber2);
cmd.Parameters.AddWithValue("#parameter10", CompanyEMail2);
cmd.Parameters.AddWithValue("#parameter11", CompanyNotes2);
cmd.ExecuteNonQuery();
this.Hide();
AddingClients M1 = new AddingClients();
M1.Show();//Saves the current data then goes to the next record to be tested.
You have an extra comma before the closing ) in your column list and VALUES sections:
SqlCommand cmd = new SqlCommand("INSERT INTO ClientTable(Id, ClientName, CompanyName, CompanyAddress1, CompanyAddress2, CompanyAddress3, CompanyTown, CompanyPostCode, TelephoneNumber, CompanyEMail,
CompanyNotes,)
****
VALUES(#parameter1, #parameter2, #parameter3, #parameter4, #parameter5, #parameter6, #parameter7, #parameter8, #parameter9, #parameter10,
#parameter11,)", con);
****
Remove that and you should be fine
I am trying to write a Windows Form program on top of .NET 4.0 and accessing Microsoft Access Database. I can read and write with no problem but sometimes, I get this error:
COM object that has been separated from its underlying RCW cannot be used.
I tried to call this method (GetIDBasedonTeamName) with different inputs twice (on the same thread). The second time this is run, I got that error.
OleDbConnection conn = new OleDbConnection();
OleDbConnection mDB = new OleDbConnection();
OleDbCommand comm = new OleDbCommand();
OleDbCommand cmd;
OleDbDataReader dr;
public void OpenConnection(string name) // always call this method first in other methods to initialise connection
{
conn.ConnectionString = "Provider = Microsoft.Jet.OLEDB.4.0;Data source="
+ Application.StartupPath + "\\AppData\\" + name + ".mdb;";
conn.Open();
comm.Connection = conn;
comm.Parameters.Clear();
}
public string GetIDBasedonTeamName(string teamName)
{
string toReturn = "";
try
{
OpenConnection("form");
comm.CommandText = "Select ID from TeamDetails WHERE TeamName=#teamName";
comm.Parameters.AddWithValue("TeamName", teamName);
dr = comm.ExecuteReader();
while (dr.Read())
{
toReturn = dr[0].ToString();
}
}
catch (OleDbException e)
{
string err = e.Message.ToString();
return null;
}
finally
{
}
conn.Close();
dr.Close();
return toReturn;
}
Exception happened on dr = comm.ExecuteReader();.
The method that was calling this method have this 2 lines inside:
InfoConfig.team1id = Convert.ToInt32(dbm.GetIDBasedonTeamName(cbxTeam1.Text));
InfoConfig.team2id = Convert.ToInt32(dbm.GetIDBasedonTeamName(cbxTeam2.Text));
What could be the cause? I read around and they mentioned not to use different threads but it is the same thread here.
Thanks,
Guo Hong
Building on Martin Liversage's answer:
public string GetIDBasedonTeamName(string teamName) {
var connString = "Provider = Microsoft.Jet.OLEDB.4.0;Data source="
+ Application.StartupPath + "\\AppData\\" + name + ".mdb;";
using (var conn = new OleDbConnection(connString)) {
conn.Open();
using (var cmd = conn.CreateCommand()) {
cmd.CommandText="Select ID from TeamDetails WHERE TeamName = #teamName";
cmd.Parameters.AddWithValue("TeamName", teamName);
using (var rdr = cmd.ExecuteReader()) {
if (rdr.Read()) {
return (string)rdr["TeamName"];
}
//if no valid results will return null
}
}
}
}
Instead of creating the objects only once and storing them in fields in your class you should create, use and close the objects in your method. It is probably the Close you call in the end the method that releases the underlying COM objects giving you the exception on the second call.
I would like to know if there is any way to fill ObservableCollection directly from SQL server.
Currently I am loading my data into DataTable (using sqlDataAdapter) and do a conversion to ObservableCollection manually and it very inefficient.
How it can be done?
OK, I have found a way to do this:
It can be done using SqlDataReader.
public ObservableCollection<DataItem> LoadCategoriesData()
{
Command = new SqlCommand(StoredProcedure, Connection);
Command.CommandType = CommandType.StoredProcedure;
ObservableCollection<DataItem> myColl = new ObservableCollection<DataItem>();
Connection.Open();
SqlDataReader reader = Command.ExecuteReader();
while (reader.Read())
{
int mainCatID = reader.GetInt32(0);
string categoryName = reader.GetString(1);
//adding row data to observable
myColl.Add(new DataItem(mainCatID, categoryName));
}
Connection.Close();
return myColl;
}