C#-sql update code. Too many columns in acess database - c#

I have an c# program that update 2 columns, in each table in my access database file(.mdb). Columns that I'm updatnig are short string type, I am also changing their size to 255, before updating. I have 15 files, my code is working for first 7 dbs, and crash on 8-th file. I am updating each code separately, and it crash about in the middle of database
System.Data.OleDb.OleDbException: 'Record is too large.'
Query string that is crashing :
UPDATE CARTE SET SYMBOLE = 'AGLX19.A8E', SYMBOLE2 = 'AWLX19.A8E;#P516.#PQ;#P517.#PQ;#P518.#PQ;#P519.#PQ' WHERE CODE = '2862411';
private void UpdateSYMBOLEinDatabase(string tableName, string code)
{
if (symboleMdb[0] == "")
return;
string queryString = "UPDATE " + tableName +
" SET SYMBOLE = '" + symboleMdb[0] + "', SYMBOLE2 = '" + symboleMdb[1] + "' " +
"WHERE CODE = '" + code + "';";
if (symboleMdb[1] == "")
queryString = queryString.Replace(", SYMBOLE2 = ''", "");
using (OleDbConnection connectionInput = new OleDbConnection(connectionStringInput))
using (OleDbCommand command = new OleDbCommand(queryString, connectionInput))
{
connectionInput.Open();
command.ExecuteNonQuery();
command.Dispose();
}
}
I haved checked sql string carefully (also in online checker).
I had also search on google's and found that this error, is probably connected with too many columns in my db, actually when I am opening db file, there is about 220 columns. But when I am counting columns programmaticly it shows that there is about 878 columns(before/after changing length of short string type in columns). For others tables it shows correct count.
I found that copying table, may help. But actually I also can't do that.
private void CopyDeleteCopyDeleteQuery(string tableName)
{
string queryString = "CREATE TABLE " + tableName + "O"+
" AS (SELECT * FROM " + tableName +
" WHERE CODE='0801733');";
using (OleDbConnection connectionInput = new OleDbConnection(connectionStringInput))
using (OleDbCommand command = new OleDbCommand(queryString, connectionInput))
{
connectionInput.Open();
command.ExecuteNonQuery();
command.Dispose();
}
}
System.Data.OleDb.OleDbException: 'Syntax error in CREATE TABLE statement.'
Query string :
CREATE TABLE CARTEO AS (SELECT * FROM CARTE WHERE CODE='0801733');

The limit for fields is 2kB (excluding Memo and OLE. With ~220 columns fields, you are likely to be hitting that limit.
You should normalize the table, or convert some columns to Memo fields.

Related

String or binary data would be truncated. The statement has been terminated. when inserting into the table

In my application I am getting one row from table1 displaying it in the view and then after reply I am inserting the reply into table 2 and deleting the the entry from table 1 and getting the next question from table1.
I am getting the error:
String or binary data would be truncated. The statement has been terminated
in the httppost method. I have checked the values of the tempdata in the post method by applying a breakpoint and there is no problem with it.
The values in the database are of type nvarchar except the id which is of int type.
I am not able to find why I still get the error. The error shows in the execute method but I am not able to find the reason behind it.
The things that I am inserting are mostly strings and some may contain special character in the string like * , \ etc and up to 700 characters.
PS: Presently I have ignored SQL injection threat
[HttpGet]
public ActionResult Index()
{ string connstr = "Here is the connection string";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
SqlCommand cmd = new SqlCommand(" Select top(1) Id , Body , Email_subject , Queue , Intent , Tagging FROM
table1 ");
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = conn;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
var Did = reader["Id"].ToString();
TempData["id "] = Int64.Parse(Did);
TempData["subject "] = reader["Email_subject"].ToString();
TempData["body"] = reader["Body"].ToString();
TempData["intent"] = reader["Intent"].ToString();
TempData["queue"] = reader["Queue"].ToString();
TempData["tagging"] = reader["Tagging"].ToString();
}
conn.Close();
TempData.Keep();
return View();
}
[HttpPost]
public ActionResult Index(string Correctornot)
{ TempData.Keep();
string connstr = My connection String;
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
SqlCommand cmd = new SqlCommand("SET IDENTITY_INSERT table2 ON ; INSERT INTO table2 ( Id ,Body, Response ,Queue , Intent , Tagging , Email_subject) VALUES ( '" + TempData["id"] + "' , '" + TempData["body"] + "'
, '" + Correctornot + "' , '" + TempData["Queue"] + "' , '" + TempData["intent"] + "' , '" + TempData["tagging"] + "' , '" + TempData["subject"] + "');DELETE FROM table1 where Id = '" + TempData["id"] + "' ;");
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = conn;
SqlDataReader reader2 = cmd.ExecuteReader();
SqlCommand cmd2 = new SqlCommand(" Select top(1) Id , Body , Email_subject , Queue , Intent , Tagging FROM table1");
cmd2.CommandType = System.Data.CommandType.Text;
cmd2.Connection = conn;
SqlDataReader reader3 = cmd2.ExecuteReader();
while (reader3.Read())
{
var Did = reader3["Id"].ToString();
TempData["id "] = Int64.Parse(Did);
TempData["subject "] = reader3["Email_subject"].ToString();
TempData["body"] = reader3["Body"].ToString();
TempData["intent"] = reader3["Intent"].ToString();
TempData["queue"] = reader3["Queue"].ToString();
TempData["tagging"] = reader3["Tagging"].ToString(); }
conn.Close();
TempData.Keep();
return View(); }
Solution:
I was able to solve the problem but I still don't know the reason behind it.
The problem was due to the value returned by clicking the button. Though the value was not too large ( it was just "correct " and "not correct") , when i tried to insert it into the database it gave me the error .
I solved it by using a switch statement instead of directly adding it to the insert statement.
i.e
switch (Correctornot)
{
case "Correct":
sql = "Insert INTO [dbo].[Labeler_Email_For_confirmation_Agents](Body , Response , Queue , Intent , Tagging , Email_subject ) Values ( '" + TempData["body"].ToString() + "' , 'yes' , '" + TempData["queue"].ToString() + "' , '" + TempData["intent"].ToString() + "' , '" + TempData["tagging"].ToString() + "' , '" + TempData["email_subject"].ToString() + "');";
break;
case "Not Correct":
sql = "Insert INTO [dbo].[Labeler_Email_For_confirmation_Agents](Body , Response , Queue , Intent , Tagging , Email_subject ) Values ( '" + TempData["body"].ToString() + "' , 'no' , '" + TempData["queue"].ToString() + "' , '" + TempData["intent"].ToString() + "' , '" + TempData["tagging"].ToString() + "' , '" + TempData["email_subject"].ToString() + "');";
break;
}
SQL Server 2016 SP2 CU6 and SQL Server 2017 CU12
introduced trace flag 460 in order to return the details of truncation warnings.
You can enable it at the query level or at the server level.
Query level
INSERT INTO dbo.TEST (ColumnTest)
VALUES (‘Test truncation warnings’)
OPTION (QUERYTRACEON 460);
GO
Server Level
DBCC TRACEON(460, -1);
GO
From SQL Server 2019 you can enable it at database level:
ALTER DATABASE database_name
SET COMPATIBILITY_LEVEL = 150
ALTER DATABASE SCOPED CONFIGURATION
SET VERBOSE_TRUNCATION_WARNINGS = ON;
The old output message is:
Msg 8152, Level 16, State 30, Line 13
String or binary data would be truncated.
The statement has been terminated.
The new output message is:
Msg 2628, Level 16, State 1, Line 30
String or binary data would be truncated in table 'DbTest.dbo.TEST', column 'ColumnTest'. Truncated value: ‘Test truncation warnings‘'.
In a future SQL Server 2019 release, message 2628 will replace message 8152 by default.
"String or binary data would be truncated. The statement has been terminated" is reporting that one of the values you are trying to insert is too large for the SQL Column. For example, you'll see this error if you try insert "Hello, World" into a SQL Column that can only hold 4 characters. Truncate the value before inserting, or change the datatype of the SQL Column.

How to get all records from one table and save it on another table by c# in winforms?

Hello guys, i am trying to get all records from tblInvoiceItemsTemp table and save all the records inside the tblInvoiceItems table but not able to solve. Any help would be appreciated, thank you.
I have added following code on btnSave_Click() event.
string connetionString1 = "server=localhost;database=billingDB;uid=root;pwd=root;integrated security=true";
using (MySqlConnection cnn1 = new MySqlConnection(connetionString1))
{
cnn1.Open();
string load_temp_table_rec_qry = "SELECT * FROM tblInvoiceItemsTemp";
using (MySqlCommand sqlcmd = new MySqlCommand(load_temp_table_rec_qry, cnn1))
{
MySqlDataReader temp_reader = sqlcmd.ExecuteReader();
while (temp_reader.Read())
{
string insert_invoice_items_qry = "INSERT INTO tblInvoiceItems(invoiceID, particulars, qty, rate) VALUES('" + 12 + "', '" + temp_reader["particulars"] + "', '" + temp_reader["qty"] + "', '" + temp_reader["rate"] + "')";
using (MySqlCommand itemsCmd = new MySqlCommand(insert_invoice_items_qry, cnn1))
{
itemsCmd.ExecuteNonQuery();
}
}
}
cnn1.Close();
}
I am getting following error messages.
An unhandled exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll
Additional Information: There is already an open DataReader associated with this Connection which must be closed first.
The error message is pretty clear: while you have a DataReader open (you haven't called Close/Dispose), the Connection cannot be used for anything else. One way to do this is to open a second connection:
using (MySqlCommand sqlcmd = new MySqlCommand(load_temp_table_rec_qry, cnn1))
{
MySqlDataReader temp_reader = sqlcmd.ExecuteReader();
using (var secondConnection = new MySqlConnection(connetionString1))
{
secondConnection.Open();
while (temp_reader.Read())
{
string insert_invoice_items_qry = "INSERT INTO tblInvoiceItems(invoiceID, particulars, qty, rate) VALUES('" + 12 + "', '" + temp_reader["particulars"] + "', '" + temp_reader["qty"] + "', '" + temp_reader["rate"] + "')";
using (MySqlCommand itemsCmd = new MySqlCommand(insert_invoice_items_qry, secondConnection))
{
itemsCmd.ExecuteNonQuery();
}
}
}
}
Another way is to use the disconnected model and load the records to a DataTable using a MySqlDataAdapter, so that the connection is free for using for itemsCmd.
However, you don't need to download into memory all the records for this, you can do an INSERT INTO SELECT, for much better performance:
INSERT INTO tblInvoiceItems(invoiceID, particulars, qty, rate)
SELECT 12, tblInvoiceItemsTemp.particulars, tblInvoiceItemsTemp.qty, tblInvoiceItemsTemp.rate
FROM tblInvoiceItemsTemp

Error : Conversion failed when converting date and/or time from character string

In SQL table Date_Of_Birth and Date_Of_Joining data type is date. I need to perform update.
I have this code and it's showing an error - Conversion failed when converting date and/or time from character string.
Please help.
string sql = "UPDATE Employees SET Designation = '" +textBox_BEUpdtD.Text +
"', Employee_Subgroup = '" +comboBox_BEupdt.Text +
"', Date_Of_Birth = " + dateTimePicker_DOBUpdt.Text +
", Date_Of_Joining = " + dateTimePicker_DojUpdt.Text +
" Where Employee_Name ='"+comboBox_EmpNm.Text+"' ";
SqlCommand cmd7 = new SqlCommand(, con7);
con7.Open();
int o = cmd7.ExecuteNonQuery();
MessageBox.Show(o +" : Record has been updated"); '
Aside from the SQL Injection issues with sending in user variables directly to the database, I suggest using parameterized queries to simplify what you're trying to do.
SqlCommand cmd7 = new SqlCommand("UPDATE Employees SET Designation = #designation, Employee_Subgroup = #subgroup, Date_Of_Birth = #dateofbirth, Date_Of_Joining = #dateofjoining Where Employee_Name = #employeename", con7);
cmd7.Parameters.AddWithValue("designation", textBox_BEUpdtD.Text);
cmd7.Parameters.AddWithValue("subgroup", comboBox_BEupdt.Text);
cmd7.Parameters.AddWithValue("dateofbirth", dateTimePicker_DOBUpdt.Value.Date);
cmd7.Parameters.AddWithValue("dateofjoining", dateTimePicker_DojUpdt.Value.Date);
cmd7.Parameters.AddWithValue("employeename",comboBox_EmpNm.Text);
con7.Open();
int o = cmd7.ExecuteNonQuery();
MessageBox.Show(o +" : Record has been updated")
That said, there are some issues with your database schema. I strongly suggest that you do not key on employee name, as:
A) It's not necessarily unique,
B) May be mistyped in this form as it's just a pure text box,
C) May change over time (eg. marriage, etc.)

Wrong data type OleDB Create Table

I m using the following function to create an access table:
public static void createtable(string path, string tablename, string[] columnnames)
{
try
{
string connectionstring = creadteconnectionstring(path);
OleDbConnection myConnection = new OleDbConnection(connectionstring);
myConnection.Open();
OleDbCommand myCommand = new OleDbCommand();
myCommand.Connection = myConnection;
string columnam = "[" + columnnames[0] + "] Text";
for (int i = 1; i < columnnames.Length; i++)
{
columnam = columnam + ", [" + columnnames[i] + "] Text";
}
myCommand.CommandText = "CREATE TABLE [" + tablename + "](" + columnam + ")";
myCommand.ExecuteNonQuery();
myCommand.Connection.Close();
Console.WriteLine("Access table " + tablename + " created.");
}
catch
{
Console.WriteLine("Access table " + tablename + " already exists.");
return;
}
}
However if I open the access table in MS access the data type is Memo, not Text. Other data types link specified by MS dont seem to work at all.
Any ideas are welcome? Thanks!
The Access DDL TEXT data type behaves differently depending on the context where you execute your statement.
From DAO in Access, this creates bar as a text field. But from ADO in Access, bar will be memo type.
CREATE TABLE tblFoo (bar TEXT)
Executing that statement from an OleDb connection produces the same result as with ADO in Access.
If you want bar to be an actual text field, include a field length <= 255.
CREATE TABLE tblFoo (bar TEXT(255))

How to add column to .DBF file?

One of the issues I have is that, I don't think the table has a name... its just a .dbf file
So I've been trying this:
public void SQLAlter(string dbffile, string ColumnName )
{
//dbffile is "C:\MAPS\WASHINGTON\TLG_ROADS_L.DBF"
//ColumnName is "State"
if (File.Exists(dbffile))
{
System.Data.Odbc.OdbcConnection conn = new System.Data.Odbc.OdbcConnection();
conn.ConnectionString = #"DSN=dBase Files";
conn.Open();
System.Data.Odbc.OdbcCommand comm = new System.Data.Odbc.OdbcCommand();
comm.CommandText = "ALTER TABLE " + dbffile + " ADD COLUMN " + ColumnName + " VARCHAR(1024)";
comm.ExecuteNonQuery();
}
}
The error is :
base {System.Data.Common.DbException} = {"ERROR [42S02]
[Microsoft][ODBC dBASE Driver] Cannot find table or constraint."}
I believe the table name is supposed to be the filename, and the connection string should point to the folder containing the dbf file.
var path = Path.GetDirectoryName(dbffile);
var tableName = Path.GetFileName(dbffile);
// ...
conn.ConnectionSTring = #"Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=" + path;
comm.CommandText = "ALTER TABLE " + tableName + //...
Check connectionstrings.com: http://connectionstrings.com/dbf-foxpro
This is actually the correct syntax
comm.CommandText = "ALTER TABLE " + dbffile + " ADD COLUMN " + ColumnName + " VARCHAR(1024)";
However if your filename is longer than 8 characters it will not find it. Even though I tried it will an appropriate length file name, the "Operation [is] not supported on a table that contains data."
Various Internet links seem to indicate that one has to create a new table, and copy all the fields over.
Try another Provider.
It worked for me with the Visual Foxpro Provider
conn.ConnectionString = #"Provider=VFPOLEDB.1; Data Source=Themes.dbf" + #"\;Extended Properties=dBase IV";
If the driver is not installed on your machine, you get it here :
http://www.microsoft.com/en-us/download/details.aspx?id=14839

Categories

Resources