How To Insert Into DBF File (foxpro) - c#

I have the following code in asp.net:
using (OleDbCommand command = dbConnW.CreateCommand())
{
string CreateTableK = null;
CreateTableK += "Create Table DSKKAR00 (DSK_ID c(10),DSK_KIND N(1),MON_PYM C(3))";
OleDbCommand cmdCreateTable = new OleDbCommand(CreateTableK, dbConnW);
cmdCreateTable.ExecuteNonQuery();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(WorkRoomNo + ",");
sb.Append("1,");
sb.Append(",");
OleDbCommand cmd3 = new OleDbCommand("Insert into DSKKAR00 (DSK_ID,DSK_KIND,MON_PYM) Values (" + sb.ToString() + ")", dbConnW);
cmd3.ExecuteNonQuery();
But I have the following error:
Syntax error

In addition to what Chris has offered, you are starting your CREATE TABLE with a NULL string variable, then doing a += to it. From what I remember, a NULL += "anystring" will remain a null value... You might be crashing right there too.
Although VFP is not really suceptible to SQL Injection like other SQL engines, its good habit to do parameterizing. When you do, use "?" as a place-holder for the value you want to insert, and add parameters in the same order sequence as the "?" represent.
string CreateTableK =
"Create Table DSKKAR00 (DSK_ID c(10),DSK_KIND N(1),MON_PYM C(3))";
OleDbCommand cmdCreateTable = new OleDbCommand(CreateTableK, dbConnW);
cmdCreateTable.ExecuteNonQuery();
string MyInsert =
"insert into DSKKAR00 ( dsk_id, dsk_kind, mon_pym ) values ( ?, ?, ? )";
OleDbCommand cmd3 = new OleDbCommand( MyInsert, dbConnW);
cmd3.Parameters.AddWithValue( "parmSlot1", WorkRoomNo );
cmd3.Parameters.AddWithValue( "parmSlot2", 1);
cmd3.Parameters.AddWithValue( "parmSlot3", 'tst' ); // or whatever variable to put
cmd3.ExecuteNonQuery();

First off, any time you have an error it's usually best to post the entire error message you get.
Also, when trying to debug a query problem, you should emit the actual query being sent to your server/database and inspect it. This way you can find various problems like too many commas.
Speaking of which, looking at your code, you are concatenating a String and it really looks like you have way too many commas.
The emitted query looks like it will be:
insert into DSKKAR00(DSK_ID, DSK_KIND, MON_PYM) VALUES( X,1, ,)
where X is the value of your WorkRoomNo variable.
Obviously, that isn't valid syntax and would result in the error you've seen. The commas indicate there are 4 values being passed, but the insert query only identifies 3 columns.
The next issue has to do with the column definitions themselves. The first column of that table is a c(10); the third is a c(3). I'm a little rusty, but aren't those character fields?
If so then you need to adjust your string builder to add the appropriate quotes around the values...
Which leads us to the final problem: Don't use String concatentation to build queries. Use Parameterized queries

Related

Setting SQL query parameter to Int32 in C#

I'm having problems with some code I'm trying to write. I'm doing something for suppliers orders, so I have a table which is named "encomendas_fornecedores" with a autoincrement field before the key that is the code of sale which consists in a EF before the number(which is a text field).
Here is the code:
connection.Open();
OleDbCommand comando1 = new OleDbCommand();
OleDbCommand comando2 = new OleDbCommand();
OleDbCommand comando3 = new OleDbCommand();
comando1.Connection = connection;
comando2.Connection = connection;
comando3.Connection = connection;
comando1.CommandText = "INSERT INTO encomendas_fornecedores (cod_encomenda_forn, cod_metodo, cod_forn, total_pagar_forn) VALUES('FO', '" + txtcodmetodo.Text + "', '" + txtcodforn.Text + "', '" + lbltotalapagar.Text + "'); ";// insert into table the values with a FO to cod
comando1.ExecuteNonQuery();
comando2.CommandText = "Select MAX(num_encomenda) From encomendas_fornecedores;";// selecting maximum num encomenda so I can isolate it and add to a text before(btw I do this in php/sql no problems
int numero = Convert.ToInt32(comando2.ExecuteScalar());//max num_encomenda
string codencomendaforn= "EF"+Convert.ToString(numero);// sales code completed
comando3.CommandText = "UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = '"+ numero +"';";//query that is giving me the problems, it says something like "type of data incorrect in data expression"
comando3.ExecuteScalar();//giving me error this line
connection.Close();
But now here's the catch the cod_encomenda_forn is text and the num_encomenda auto increment as it is in the sql, and I tried to show the query in a textbox to see if its anything is wrong but nothing seems wrong.
"UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = **'**"+ **numero** +"**'**;";//query that is giving me the problems,it says something like "type of data incorrect in data expression"
You are passing a string numero to a where statement that seems like it is expecting a number. As long as it is numeric it should work, but definitely not gauranteed to work. Second you are passing anothercodencomendaforn string to encomenda what is encomenda 's data type?
It appears that you are not handling potential datatype differences between your c# code and your SQL query. In addition single quoting '' around a value in a SQL statement tells the database engines that it is a string even if that is '1234'. While SQL will automatically convert some values it doesn't always. In addition c# .net library also looks for some conversion etc. before sending the SQL statement. To fix appropriately use parameters that are data typed to the database type in the SQL table. To fix it simply in the statement figure out your data types and fix the '' single quotes appropriately.
PS the people trying to help you in the comments were being nice and telling you the professional way of keeping your job in the future when you graduate after fixing this issue.

Syntax error when inserting many columns into MySQL

I'm trying to insert some data into a MySQL database using the below C# code. If I run this command it throws an exception like the following:
some error: You have an error in your SQL syntax; check the manual that correspo
nds to your MySQL server version for the right syntax to use near ': The Third Reich,
,
' at line 25
Is there a syntax error somewhere? I can't find anything wrong.
var rowContent = String.Format(#"
INSERT INTO animes
(
`JapanTitle`,
`AmericanTitle`,
`GermanTitle`,
`AnimeType`,
`CoverPath`,
`Episodes`,
`MinutesPerEpisodes`,
`JapanStatus`,
`AmericanStatus`,
`GermanStatus`,
`JapanTimeSpan`,
`AmericanTimeSpan`,
`GermanTimeSpan`,
`MainGenres`,
`SubGenres`,
`JapanStudios`,
`AmericanStudios`,
`GermanStudios`,
`GermanDescription`,
`EnglishDescription`)
VALUES
({0},
{1},
{2},
{3},
{4},
{5},
{6},
{7},
{8},
{9},
{10},
{11},
{12},
{13},
{14},
{15},
{16},
{17},
{18},
{19});", entity.JapanTitle,
entity.AmericanTitle,
entity.GermanTitle,
entity.AnimeType.ToString(),
entity.WallPaper.FileName,
entity.Episodes,
entity.MinutesPerEpisode,
entity.JapanStatus.ToString(),
entity.AmericanStatus.ToString(),
entity.GermanStatus.ToString(),
entity.JapanTimeSpan.ToString(),
entity.AmericanTimeSpan.ToString(),
entity.GermanTimeSpan.ToString(),
string.Join(",", entity.MainGenres),
string.Join(",", entity.SubGenres),
string.Join(",", entity.JapanStudios),
string.Join(",", entity.AmericanStudios),
string.Join(",", entity.GermanStudios),
entity.GermanDescription,
entity.EnglishDescription);
If I look at this code, I think it is pretty bad code. Is there a better way to insert many columns into a database without something like the entity framework?
Your main error is caused by the missing quotes around your strings. In a sql command text, when you want to pass a value for a text field you need to put this value between single quotes.
But also with appropriate quotes around your values you have another big problem called Sql Injection.
The only secure way to use a command like that is through a parameterized query.
Something like this (I will cut your code because is too long)
string cmdText = #"INSERT INTO animes
(JapanTitle,AmericanTitle,GermanTitle,AnimeType,.....)
VALUES(#japtitle, #usatitle, #germantitle, #animtype, ....)";
MySqlCommand cmd = new MySqlCommand(cmdText, connection);
cmd.Parameters.AddWithValue("#japtitle", entity.JapanTitle);
cmd.Parameters.AddWithValue("#usatitle", entity.AmericanTitle);
cmd.Parameters.AddWithValue("#germantitle", entity.GermanTitle);
cmd.Parameters.AddWithValue("#animtype", entity.AnimeType);
....
cmd.ExecuteNonQuery();
In this way you don't write directly the values in the command text, but put placeholders for the parameters value. It is the database engine that will figure out how to use the parameters passed along the command. (And no need to worry about quotes around your string or escape quotes that are part of your values)
Notice also that the AddWithValue method of the Parameters collection has its own quirks. You need to pass the value with the exact datatype expected by the database field (So, no ToString() for AnimeType if the field expects an integer)
First of all, your database should probably look something like this:
An animes table with non-language values like CoverPath, Episodes, etc. - one row per movie
An animes_lang table with language-specific values like Title, Status, TimeSpan, Studios, etc. - one row per language per movie
That would probably make it easier to maintain.
At any rate, I can make the query construction a little easier but you'll need to specify all of the parameters.
String[] cols = {
"JapanTitle",
"AmericanTitle",
"GermanTitle",
"AnimeType",
"CoverPath",
"Episodes",
"MinutesPerEpisodes",
"JapanStatus",
"AmericanStatus",
"GermanStatus",
"JapanTimeSpan",
"AmericanTimeSpan",
"GermanTimeSpan",
"MainGenres",
"SubGenres",
"JapanStudios",
"AmericanStudios",
"GermanStudios",
"GermanDescription",
"EnglishDescription"
};
String query =
"INSERT INTO animes (" + String.Join(", ", cols) +
") VALUES (" + String.Join(", #", cols) + ");";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("#JapanTitle", entity.JapanTitle);
cmd.Parameters.AddWithValue("#AmericanTitle", entity.AmericanTitle);
cmd.Parameters.AddWithValue("#GermanTitle", entity.GermanTitle);
. . .
cmd.Parameters.AddWithValue("#EnglishDescription", entity.EnglishDescription);
cmd.ExecuteNonQuery()
Please use Steve's answer or this one. Don't go the String.Format route. It may be that SQL Injection isn't a worry here, but make a habit of doing this the safe and right way.

SQL Parameters Inside A Loop

i have a list that i am pulling things out of to insert into a database. This is not going to be a web app so i have just been doing as follows:
string sqlStorage = (null,"asd"),
for (int i = 1; i < listsize; )
{
sqlStorage = sqlStorage + "(null,someVariableFromLoop)";
i++
}
string connString = "Server=localhost;...........";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = #"INSERT INTO table1 VALUES " + tempSQLStorage;
etcetc...
However
"someVariableFromLoop"
is a large amount of text which includes all kinds of horrible code breaking characters. quotation marks etc etc.
So i looked into parameters (the way i should be doing SQL i know, i know), however i was unable to find a way to store these parameters inside the loop. i dont want to hit the DB every single iteration. I had a go at something along the lines of
"#variable"+i.toString();
but could not get it to work at all.
So does anyone have any idea how i would go about storing the parameters and the execute the query? Thanks in advance!
So i looked into parameters (the way i should be doing SQL i know, i know), however i was unable to find a way to store these parameters inside the loop. i dont want to hit the DB every single iteration. I had a go at something along the lines of
"#variable"+i.toString();
but could not get it to work at all.
Well, what was the error you received? Because that's the way you do it. Here's an example for MSSQL and I know the technique works, because I've done similar before:
int i = 0;
List<string> clauses = new List<string>() {"(#key0, #value0)"};
List<SqlParameter> paramList = new List<SqlParameter> {
new SqlParameter("#key0", DBNull.Value),
new SqlParameter("#value0", "asd")
};
for (i = 1; i < listSize; i++) {
clauses.Add("(#key" + i + ", #value" + i + ")");
paramList.Add(new SqlParameter("#key" + i, someKey));
paramList.Add(new SqlParameter("#value" + i, someValue);
}
SqlConnection conn = new SqlConnection(connString);
SqlCommand command = new SqlCommand(conn, #"INSERT INTO table1 VALUES " + String.Join(", ", clauses);
foreach(SqlParameter param in paramList) command.Parameters.Add(param);
command.ExecuteNonQuery();
Note, above code is quick and dirty. Obviously using statements and various other best practices should be incorporated as well for production code.
Also look at this: How do you use the MySql IN clause. It has an example of dynamically creating and passing parameters to the query, but for an SELECT...IN clause vs. INSERT...VALUES.
To ensure secure code (and avoid malformed queries), use SQL Command objects with Parameters. There is nothing horribly wrong with executing the command once for every record - a little extra overhead for round-trips over the network, but if the text is long you might have to do this anyway since queries do have a character limit.

how to add ' like special characters in mysql varchar data type column?

I am trying to insert string as "baby's world" into the column of type varchar through query but shows me error.
Is there anything else i need to put to the query so that it accept that symbol
put a backslash in front of it like so:
"Baby\'s world"
You can find and replace them in your string using the following:
str.Replace('\'', '\\\'')
I'm not 100% sure about this last part, but you need to 'escape' the ' and \ by adding a \ in front of it. So it would seem alright (can't test as i'm not a C# programmer.
Since you are asking about Visual Studio (.NET), you need to use parameterized query. Don't use concatenation when constructing query
private void PrepareExample()
{
string s = Console.ReadLine();
MySqlCommand cmd = new MySqlCommand("INSERT INTO movie(title) VALUES (?title)", myConnection);
cmd.Parameters.AddWithValue( "?title", "baby's world" );
cmd.Prepare();
cmd.ExecuteNonQuery();
}
Or
private void PrepareExample()
{
MySqlCommand cmd = new MySqlCommand("INSERT INTO movie(title) VALUES (?title)", myConnection);
// try to input: baby's world. or try: baby"s world. everything are ok :-)
cmd.Parameters.AddWithValue( "?title", Console.ReadLine() );
cmd.Prepare();
cmd.ExecuteNonQuery();
}
Though this is not exactly concatenation, don't use this:
qry = string.Format("INSERT INTO movie(title) VALUES("{0}", Console.ReadLine());
Though if you really found a need to run SQL that way, replace single quote with backslash
qry = string.Format("INSERT INTO movie(title) VALUES("{0}",
Console.ReadLine().Replace("'", "\'");
But do consider using parameterized query instead of concatenation or string.Format, as parameterized query automatically take care of those delimeter nuances.
http://dev.mysql.com/doc/refman/5.0/es/connector-net-examples-mysqlcommand.html
Just use mysql_real_escape_string(). There is no need to do anything else.
For example:
mysql_real_escape_string($user),
mysql_real_escape_string($password));
INSERT INTO table (field) VALUES ('baby's world') will fail because the string is truncated to INSERT INTO table (field) VALUES ('baby' and the rest is seen as invalid code.
There are two ways to stop this, the second being advisable for good practice coding:
INSERT INTO table (field) VALUES ("baby's world")
INSERT INTO table (field) VAUES ('baby\'s world')

ODP.NET InsertCommand erroneously returns ORA-01401: inserted value too large for column

I've got a C# function that is constructing a parameterized insert query using ODP.NET that for some reason keeps returning the "ORA-01401: inserted value too large for column" exception.
I've thoroughly checked the length of the string variable in question and it falls well beneath the maximum size of the database column (70 chars long in a 1024 chars long Varchar2 column). What's stranger is that if I insert the value as a string rather than a parameter variable, the insertion works just fine. Here's the code (parameterized):
connectionString = GetConnectionString();
conn = new OracleConnection(connectionString);
OracleDataAdapter oda = new OracleDataAdapter();
conn.Open();
insertStatement = "INSERT INTO DOCS (ID, PATH, PAGES, USERID,SUFFIX, MASK) ";
insertStatement += "VALUES (:id, :itemUrl, 1, 'SHAREPOINT\\system',0,'000') ";
oda.InsertCommand = new OracleCommand(insertStatement, conn);
oda.InsertCommand.Parameters.Add(":id", docList[0].taskerID.ToString());
oda.InsertCommand.Parameters.Add(":itemUrl", itemUrl);
count += oda.InsertCommand.ExecuteNonQuery();
I'm thinking that maybe there's something I'm missing here with ODP.NET or there is actually a bug with ODP.NET that I'm encountering. I'm using version 9.2.0.7 of Oracle.DataAccess on my server. Any ideas?
I got this to work with just a slight modification of your code, but I did not receive the same exception as you.
The only changes I did was to add "INTO" into the INSERT statement as well as double quoting the paramater names in the add collection items.
create table DOCS (id varchar2(70) , path varchar2(70) , pages number, userid varchar2(70) , suffix varchar2(70), mask varchar2(70));
OracleDataAdapter oda = new OracleDataAdapter();
insertStatement = "INSERT INTO DOCS (ID, PATH, PAGES, USERID,SUFFIX, MASK) ";
insertStatement += "VALUES (:id, :itemUrl, 1, 'SHAREPOINT\\system',0,'000') ";
conn.Open();
oda.InsertCommand = new OracleCommand(insertStatement, conn);
oda.InsertCommand.Parameters.Add(":id", "test1");
oda.InsertCommand.Parameters.Add(":itemUrl", "test2");
count += oda.InsertCommand.ExecuteNonQuery();
I think you may have something else going on that is not apparent in your sample.
I know that I have received your error (many many times) when I have the parameters in a cardinal order that differs from expected param collection.
This is caused by ODP binding by position by default AND NOT BINDING BY NAME (like the old Ms oraClient did).
You can either verify that the parameters are indeed in the correct position or simply:
oda.InsertCommand.BindByName = true ;
hth

Categories