I'm writing a simple desktop application in which I'm using a local SQL database (SQL Server CE). Here is the problematic section:
SqlCeConnection conn = new SqlCeConnection("Data Source=|DataDirectory|\\App_Data\\Rosters.sdf");
System.Data.SqlServerCe.SqlCeCommand cmd = new SqlCeCommand();
cmd.Connection = conn;
cmd.CommandText = String.Format("Insert into Teams (LeagueID, TeamName, Color) values ({0},'{1}','{2}');SELECT ##IDENTITY;", leagueID, txtTeamName.Text.Replace("'", "''"), txtColor.Text.Replace("'", "''"));
conn.Open();
int teamID = (int)cmd.ExecuteScalar();
conn.Close();
The problem is that I'm getting an exception when I call cmd.ExecuteScalar.
The exception message reads,
{"There was an error parsing the query. [ Token line number =
1,Token line offset = 97,Token in error = SELECT ]"}
I have run the exact same command in the exact same database through a direct query, and it runs fine - which makes me think the problem is not with SQL Server CE.
Any help would be greatly appreciated.
SQL Server Compact only supports a single statement per command, so first run the insert statement with executenonquery, then get the identity with executescalar, and remember not to close the connection in between
Related
I have a server that executing SQL queries against Azure SQL Server using ADO.NET
When I'm trying to run a specific query by my server (using ADO.NET) I get a timeout error, but when I'm executing the same query by SQL Server, I get results after 1-2 seconds.
I tried to increase to timeout in the connection string and in the SqlCommand object with no results.
I saw one potential solution to change the timeout in the SqlCommand object to 0, I tried and got results after a long time, but it works only on my local machine and not on my production server
This is the code I'm using in my server to integrate my DB:
using (var connection = new SqlConnection(ConnectionString))
{
var command = new SqlCommand
{
CommandText = query
};
foreach ( var parameter in parameters)
command.Parameters.AddWithValue(parameter.Key, parameter.Value ?? Convert.DBNull);
command.Connection = connection;
try
{
_logger.Info("Open connection to db");
connection.Open();
_logger.Info("Execute command");
SqlDataReader reader = command.ExecuteReader();
List<Column> columns = CreateColumnList(reader);
}
catch (Exception e)
{
_logger.Error(e);
}
}
This is the exception message I get:
The timeout to perform has expired. The timeout period passed before completing the action or the server is not responding
Instead of AddWithValue, specify the actual column database type and max length. For example:
command.Parameters.Add(parameter.Key, SqlDbType.VarChar, 30).Value = parameter.Value ?? Convert.DBNull);
This practice will ensure the parameter type and length matches that of the underlying column and facilitate efficient index use by the query. A big problem with AddWithValue is that it will infer data type nvarchar with strings, which will prevent a SARGable expression against an varchar column with a SQL collation.
The reason the SSMS query runs fast is likely because the ad-hoc query specifies a varchar literal or variable.
Why do I get an exception when trying to truncate a MySQL table (using MySQL Connector/Net)? I am trying to give the table name with a parameter.
This is the code I'm executing:
var connectionString = "Server="+_server+";Uid="+_user+";Pwd="+_password+";Database="+_database+";";
try
{
using (var conn = new MySqlConnection(connectionString))
{
conn.Open();
const string sql = "TRUNCATE TABLE #tablename"; // also tried with TRUNCATE #tablename
var cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#tablename", "test");
cmd.ExecuteNonQuery();
conn.Close();
}
}
catch (MySqlException ex)
{
Console.WriteLine(ex.ToString());
}
And this is the execption:
MySql.Data.MySqlClient.MySqlException (0x80004005): You have an error
in your SQ L syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near ''test'' at line 1
When I try a select query, for example, then I don't have any problems. This runs fine and returns correct data:
conn.Open();
const string sql = "SELECT body FROM test WHERE id=#pid";
var cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#pid", 1);
cmd.ExecuteScalar();
conn.Close();
Parameters are used for query values, not object names like tables.
So this will not work for sure.
You need to set the table name in the command string by using string concatenation. You can avoid sql injection attacks by manually checking for weird characters in the table name (spaces, dashes, semicolons, etc..)
I've been playing around with this for a while now, and i can't seem to get it to work either. I can't find any documentation online, so i'm starting to think you may not be able to truncate with a parameter like you've tried.
However, is there really a need to prevent SQL injection on this command? Does the user enter the name of the table they want to truncate, and if so, they're just going to truncate a table which...is essentially what the command does anyway?
I need a sample C# (console application) code witch connects to an SQL Server Express database
and inserts a few variables into a table "laptops"
SQL Server Express is # localhost
user name is database
and password is testdatabase
What is the proper way to do that ?
Basic ADO.NET 101:
set up a connection
set up a command to do something
execute that command
Step 1: setting up a connection
You need to know the connection string to your database. Check out http://www.connectionstrings.com for a ton of examples.
In your case, you say it's a local SQL Server Express instance - but unfortunately, you didn't mention what your database is called..... your connection string will be something like:
server=(local)\SQLEXPRESS;database=YourDatabaseName;user id=database;pwd=testdatabase
Step 2: setting up a command
You can have various commands - to select data, to delete that, or to insert data. Whatever you do - I would recommend to always use parametrized queries to avoid SQL injection.
So your code here would look something like:
string connectionString = "server=(local)\SQLEXPRESS;database=YourDatabaseName;user id=database;pwd=testdatabase";
string insertStmt = "INSERT INTO dbo.Laptops(Name, Model, ScreenSize) " +
"VALUES(#Name, #Model, #Screensize)";
using(SqlConnection conn = new SqlConnection(connectionString))
using(SqlCommand cmd = new SqlCommand(insertStmt, conn))
{
// set up the command's parameters
cmd.Parameters.Add("#Name", SqlDbType.VarChar, 100).Value = "ASUS SX30";
cmd.Parameters.Add("#Model", SqlDbType.VarChar, 50).Value = "Ultralight";
cmd.Parameters.Add("#Screensize", SqlDbType.Int).Value = 15;
// open connection, execute command, close connection
conn.Open();
int result = cmd.ExecuteNonQuery();
conn.Close();
}
I am trying to Insert a record in MS Access DB using OLEDB in windows application.
I am getting an error "missing semicolon at end of sql statement" there is no syntax error in sql insert statment.
My code
This is the insert statement i am using:
INSERT INTO Student
VALUES ('SRI-10-101','001','guru','30/05/2010 12:00:00 AM','','','','','','','600028','','','','','','','30/05/2010 11:25:44 AM','');
along with the code:
conn = this.GetConnection();// which returns Connection object
tran = conn.BeginTransaction();
OleDbCommand cmd = conn.CreateCommand();
cmd.Connection = conn;
cmd.CommandText = strQuery;// Insert statement
cmd.CommandType = CommandType.Text;
cmd.Transaction = tran;
cmd.ExecuteNonQuery();
tran.Commit();
I tried with semicolon also still i get error;
Thanks
It looks like you want to set your strQuery to the value of your insert statement.
Based on your code it should look something like this:
string strQuery = "INSERT INTO Student
VALUES ('SRI-10-101','001','guru','30/05/2010 12:00:00 AM','','','','','','','600028','','','','','','','30/05/2010 11:25:44 AM','')";
As always you should verify that you are connected and defaulted to the proper database (or specify it explicitly prior to your table name (i.e. MyAwesomeDatabase.dbo.Student).
Finally it also looks like you are trying to insert a number as a character array ('001' or '600028'), if the fields in your database are of a numeric type then SQL prefers numbers without quote delimiters.
Good luck!
I'm calling the code below.
On the line (IDataReader dr = cmd.ExecuteReader()) sql barfs with an Incorrect syntax near 'CompanyUpdate'.
using (SqlCommand cmd = new SqlCommand("CompanyUpdate"))
{
cmd.Parameters.Add("#CompanyID",SqlDbType.Int);
cmd.Parameters.Add("#Description",SqlDbType.VarChar,50);
cmd.Parameters["#CompanyID"].Value = companyid;
cmd.Parameters["#Description"].Value = description;
SqlConnection cn = new SqlConnection("Data Source=[datasource];Initial Catalog=dotNext;User ID=[user];Password=[password];Pooling=True;Application Name=dotNext");
cn.Open();
cmd.Connection = cn;
using (IDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
{
this.CompanyID = dr.GetInt32(0);
}
}
}
I had a look at sqlprofiler and noticed the following:
exec sp_executesql N'CompanyUpdate',N'#CompanyID int,#Description varchar(50)',#CompanyID=56,#Description='APC'
Its wrapping my command wit a sp_executesql. All my other sql commands are just executed with no issues.
So my question is two fold:
1. Why is it using sp_executesql?
2. What am I doing wrong?
Details: sql2005, c#, vs2005
I notice that you've not set the CommandType to StoredProcedure... I don't know if that's the cause of your problem or not:
cmd.CommandType = CommandType.StoredProcedure;
I've done this so many times myself I can't count.
Tip to trigger your memory when this throws exceptions next time:
Have SQL Query Profiler open while you're running your app. When each command executes, it shows the SQL generated and run on the server side. If the SQL generated begins with sp_executesql followed by your query then it's being run as a regular query - i.e. cmd.CommandType = CommandType.Text, if it starts with exec, chances are it's run as a stored proc. Make sure you're getting the correct SQL generated for the type of query you're trying to run.