I'm working on a .NET WebForms C# website and I normally use SQL Server but I have a project which is requiring use of a MySQL database, and I'm able to resolve most problems but not this last one: I can't run updates on a database or I get an error. The error I'm getting is this:
UPDATE command denied to user 'xxxx'#T'mymachine' for table 'pages'
The advice I was given to overcome this is as follows:
You need to express the login as xxxx#localhost and run it on the database server (MySQL users are bound to localhost on that server)
Slight issue is... I can't find any advice on how to express a login as a localhost user, or how to run a query as a localhost user. It defaults to xxxx#mymachine, rather than xxxx#localhost, which is why it doesn't work. Could anyone help me with how to run a query as a localhost user?
For my queries I'm connecting using the following:
Server=00.00.00.00;Database=(databasename);Uid=xxxx;Pwd=(password);
My query is a rather simple one:
MySqlConnection connection = null;
try
{
var query =
string.Format(
"UPDATE pages SET approvedDate = {1} WHERE id = {0};",
pageId, approvedDate);
connection = new MySqlConnection(Settings.Default.ConnectionString);
connection.Open();
var command = new MySqlCommand(query, connection)
{
CommandType = CommandType.Text
};
command.ExecuteNonQuery();
}
catch (Exception ex)
{
(exceptionstuff)
}
finally
{
connection?.Close();
}
Any help would be hugely appreciated.
Edit:
To stop you needing to read the comments for this, the first thing I tried was changing the username to xxxx#localhost, like this:
Server=00.00.00.00;Database=(databasename);Uid=xxxx#localhost;Pwd=(password);
and I got this error instead:
Access denied for user xxxx#localhost#mymachine
Related
To begin with: It is not a particular statement that does not work. SELECT * FROM [TABLE]; does not work either. When I run it in SSMS as user A it works perfectly fine. When I use it in C# like this:
string sqlCommand = "SELECT * FROM [TABLE];"
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Name"].ToString()))
using (var command = new SqlCommand(sqlCommand, conn))
{
conn.Open();
using (var dataReader = command.ExecuteReader())
{
while (dataReader.Read())
{
// work with results
}
}
}
I log this code block with a try-catch and I get this error message: System.Data.SqlClient.SqlException (0x80131904): The SELECT permission was denied on the object 'TABLE', database 'MyDb', schema 'dbo'.
Even if I run the program on the server where the db is, I get the same error.
My connection string looks loke this:
Data Source=Server\Something;Initial Catalog=MyDb;User ID=DOMAIN\username;Password=verySecurePassword;Trusted_Connection=True;
User A has the datareader role on the entire db.
Do you have any idea why this might be? My db admins cannot help me either and it does not appear to be a network issue, as the connection seems to work.
When you have this in your connection string:
Trusted_Connection=True;
This part of the connection string is ignored:
User ID=DOMAIN\username;Password=verySecurePassword;
Trusted connections and integrated security mean you always connect to the server as the account running your program's process. You don't get to specify the password; instead, the program will pass the authentication token issued for the user running the process, and the database will validate against that token.
If you need to use a domain login, you must run your program as that user. If you need to use a username/password, you must use Sql authentication with a non-domain account defined in Sql Server.
Im trying to update a table in C#
int record_id = 123;
using (SqlConnection connection = new SqlConnection(sqlServer)) {
SqlCommand mySqlCommand;
string sql = "UPDATE my_table SET foo = #foo WHERE id = #id;";
connection.Open();
mySqlCommand = connection.CreateCommand();
mySqlCommand.CommandText = sql;
mySqlCommand.Parameters.Add("#foo", SqlDbType.VarChar, 50);
mySqlCommand.Parameters["#foo"].Value = "bar";
mySqlCommand.Parameters.Add("#id", SqlDbType.VarChar, 50);
mySqlCommand.Parameters["#id"].Value = record_id;
mySqlCommand.ExecuteNonQuery();
connection.Close();
}
When executed, I get a 500 server error with the following message:
----- The page cannot be displayed because an internal server error has occurred. Most likely causes:
IIS received the request; however, an internal error occurred during
the processing of the request. The root cause of this error depends on
which module handles the request and what was happening in the worker
process when this error occurred.
IIS was not able to access the web.config file for the Web site or
application. This can occur if the NTFS permissions are set
incorrectly.
IIS was not able to process configuration for the Web site or
application. The authenticated user does not have permission to use
this DLL.
The request is mapped to a managed handler but the .NET Extensibility
Feature is not installed.
Im not really a C#/.NET developer and not certain about the syntax here. I do know that the line mySqlCommand.ExecuteNonQuery() causes the error.
There are also other SQL requests on the page (that I did not write) and they execute without issues. Unfortunately, none of them are update requests that I can use as an example.
protected DataTable GetData(string Query)
{
DataTable data = new DataTable();
try
{
strConnectionString = "data source=(local);Integrated Security=True;initial catalog=ps_erdb;";
string Query = "Select ErdbBuildNumbereMinor from DBVersion";
using (sqlConnection = new SqlConnection(strConnectionString))
{
sqlConnection.Open();
SqlCommand cmd = sqlConnection.CreateCommand();
cmd.CommandTimeout = intConnectionTimeout;
cmd.CommandText = Query;
data.Load(cmd.ExecuteReader());
sqlConnection.Close();
}
return data;
}
catch (Exception ex)
{
}
return data;
}
the above code returns a error
Cannot open database "ps_erdb" requested by the login. The login
failed. Login failed for user 'MIG3-ESVTB\HPSInstall'.
But when i manually open SQL Server Management Studio with above login ,i was able to connect to database and execute the query.
A few possibilities to look into:
What user were you logged in with on your local client? Your connection
string indicates you're using integrated security so the application will
present your current logged in credentials to SQL Server. To help diagnose,
make sure you enable login auditing for both failed & successful
logins. When you connect from SSMS and run SELECT suser_name(), what does it return?
Is the database set for multi_user mode (default) or single_user
mode? Someone may have changed it to single_user. This allows the
first and only one connection. All subsequent attempts will fail. If it's in single user mode, just run ALTER DATABASE ps_erdb SET MULTI_USER from SSMS
When you login via SSMS, were you able to query data from the
ps_erdb database? If not, make sure you have a database user mapped
to the 'MIG3-ESVTB\HPSInstall' login and the appropriate permissions granted to the user (not the login).
I have some problems in database connection and wonder if I have something wrong in my code. Please review. This question is related: Switch between databases, use two databases simultaneously question.
cs="Data Source=mywebsite.com;Initial Catalog=database;User Id=root;Password=toor;Connect Timeout=10;Pooling='true';"
using (SqlConnection cnn = new SqlConnection(WebConfigurationManager.ConnectionStrings["cs"].ConnectionString))
{
using (SqlCommand cmmnd = new SqlCommand("", cnn))
{
try
{
cnn.Open();
#region Header & Description
cmmnd.Parameters.Add("#CatID", SqlDbType.Int).Value = catId;
cmmnd.CommandText = "SELECT UpperID, Title, Description FROM Categories WHERE CatID=#CatID;";
string mainCat = String.Empty, rootCat = String.Empty;
using (SqlDataReader rdr = cmmnd.ExecuteReader())
{
if (rdr.Read())
{
mainCat = rdr["Title"].ToString();
upperId = Convert.ToInt32(rdr["UpperID"]);
description = rdr["Title"];
}
else { Response.Redirect("/", false); }
}
if (upperId > 0) //If upper category exists add its name
{
cmmnd.Parameters["#CatID"].Value = upperId;
cmmnd.CommandText = "SELECT Title FROM Categories WHERE CatID=#CatID;";
using (SqlDataReader rdr = cmmnd.ExecuteReader())
{
if (rdr.Read())
{
rootCat = "<a href='x.aspx'>" + rdr["Title"] + "</a> ยป ";
}
}
}
#endregion
#region Sub-Categories
if (upperId == 0) //show only at root categories
{
cmmnd.Parameters["#CatID"].Value = catId;
cmmnd.CommandText = "SELECT Count(CatID) FROM Categories WHERE UpperID=#CatID;";
if (Convert.ToInt32(cmmnd.ExecuteScalar()) > 0)
{
cmmnd.CommandText = "SELECT CatID, Title FROM Categories WHERE UpperID=#CatID ORDER BY Title;";
using (SqlDataReader rdr = cmmnd.ExecuteReader())
{
while (rdr.Read())
{
subcat.InnerHtml += "<a href='x.aspx'>" + rdr["Title"].ToString().ToLower() + "</a>\n";
description += rdr["Title"] + ", ";
}
}
}
}
#endregion
}
catch (Exception ex) { HasanG.LogException(ex, Request.RawUrl, HttpContext.Current); Response.Redirect("/", false); }
finally { cnn.Close(); }
}
}
The random errors I'm receiving are:
A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Cannot open database "db" requested by the login. The login failed. Login failed for user 'root'.
There's no real issues here.
You don't need the extraneous finally { cnn.close(); } as the using clause will take care of that for you. However changing it will have exactly zero impact.
Another thing is that I would put the try .. catch outside of the using clause with a redirect. But, again, I don't think that would affect the dispose from being called.
It's interesting that you would get connection pool errors (timeout expired) if you are always properly disposing of your connections, as you've shown.
Which leaves us with only one real solution: switch hosting providers. They have either overloaded their DB server to the point of unusability or some hardware element in their network setup (nic, switch, router, etc) is bad and dropping packets.
There are couple of inconsistencies which need to fixed:
description = rdr["Title"]; no proper casting defined.
Same command object is used for each sql statement and even you are not clearing parameters, it would be ideal if a separate command should be used for each sql statement.
Too many redirections as well, it is best to handle redirection at the end of method.
Check the database server health as well, it looks like database server is not responsive enough.
Hope it will help.
If you're connecting remotely to a database provider, you need to look at several possibilities like your own network configuration, firewall setup, etc.
Use a packet sniffer to figure out if lost packets are the issue.
Connection pooling is setup on your local machine, the server making the connections. If the database provider only allows for 5 connections and your connection pool is setup for 50 connections, well... you can do the math. It looks like you're closing the connections properly, so no issues there.
True... one error on "description = rdr["Title"];", should that be "description = rdr["Description"].ToString()"?
No need to put a using statement around the SqlCommand object and since you're using ad-hoc queries, just use string.Format("sql test {0}", param). This way, you can reuse the SqlCommand object without having to clear the parameters.
The biggest issue I see here is that you've mixed the presentation layer with the business layer with the datasource layer. Dump the try...catch and allow the business layer to handle logging stuff. Return an object to the presentation layer and allow it to perform the redirects. Keep the datasource layer very simple... get the data and return an entity. The business layer can handle any business logic on the entity itself.
SQL Server not found could be your fault or the providers... if the provider is at fault often, change providers.
Are you sure that the DB is configured to grant remote access using TCP?
I have a SQL Server 2005 box set up for merge replication to SQL Server CE 3.0. The publication, publisher, distributor and IIS have all been set up.
In my application, I attempt to sync the databases using the following code:
//TODO: Change for production
//***************************
string localDBPath = #"C:\Documents and Settings\Robert\Desktop\MyDB.sdf";
//***************************
SqlCeReplication replicator = new SqlCeReplication();
replicator.InternetUrl = "http://myWebServer/sqlcesa30.dll";
replicator.Publisher = "mySqlServer";
replicator.PublisherDatabase = "myDatabase";
replicator.PublisherSecurityMode = SecurityType.NTAuthentication;
replicator.Publication = "myPublication";
replicator.Subscriber = Dns.GetHostName();
replicator.SubscriberConnectionString = #"Data Source=" + localDBPath;
try
{
// Check if the database file already exists
if (!System.IO.File.Exists(localDBPath))
{
// Add a new subscription and create the local database file
replicator.AddSubscription(AddOption.CreateDatabase);
}
// Transfer the initial snapshot of data if this is the first time this is called.
// Subsequent calls will transfer only the changes to the data.
replicator.Synchronize();
}
catch (SqlCeException ex)
{
// Display any errors in message box
MessageBox.Show(ex.Message);
}
finally
{
// Dispose of the SqlCeReplication object, but don't drop the subscription
replicator.Dispose();
}
Unfortunately, this code fails at the "replicator.Synchronize" line with the following error message:
Failure to connect to SQL Server with provided connection information. SQL Server does not exist, access is denied because the IIS user is not a valid user on the SQL Server, or the password is incorrect.
This error message is not very clear to me and I am running out of places to look for the cause of this. Any ideas?
Make sure the agent account is the same user and password on all boxes.
Make sure you are calling the right instances.
Make sure agent is started on all machines involved.
Check the sql event logs on all servers and see which is giving the error, this may also narrow the issue down.
You can also check this to make sure you have setup correctly:
http://msdn.microsoft.com/en-us/library/aa454892.aspx
Same issue here he had to add the instance name correctly:
http://bytes.com/topic/sql-server/answers/611761-merge-replication-error-failure-connect-sql-server-provided-connection
Check these out too:
http://support.microsoft.com/kb/314783
http://support.microsoft.com/kb/319723
http://msdn2.microsoft.com/en-us/library/ms172357.aspx
again make sure you instances are correct:
repl.Publisher = "macnine-name\instance-name"
You can also take a look through this blog:
http://blogs.msdn.com/sql_protocols/archive/2005/09/28/474698.aspx
the message comes from your IIS replication plug-in: //myWebServer/sqlcesa30.dll. When it tries to connect to the publisher, it cannot find it. The publisher is named 'mySqlServer', but apparently it cannot be reached by myWebServer. This can be a name issue (a typo), a firewall issue (SQL port blocked), an IPSEC issue, a configuration issue (SQL is not listenning for remote connections) and so on. Follow normal SQL Server connectivity troubleshooting steps between myWeServer and mySqlServer.