Running stored procedure from Windows Service ad hoc access error - c#

I'm attempting to run a stored procedure that processes an excel file for import from a Windows Service developed in C#. I can run the stored procedure directly in SQL Server Management Studio, but when running the stored procedure through the service I get the following error;
Ad hoc access to OLE DB provider 'Microsoft.ACE.OLEDB.12.0' has been denied. You must access this provider through a linked server.
Microsoft.ACE.OLEDB.12.0 is listed in Server Object\Linked Servers\Providers, additionally, Disallow adhoc access is unchecked in the Provider Options.
I don't know what else to try. Any thoughts? TIA
EDIT: added some service code
public ProcessFile(string fileName)
{
this.fileName = fileName;
fileToProcess = Properties.Settings.Default.importFilePath + "\\" + fileName;
log.Debug("fileToProcess: " + fileToProcess);
OpenExcelFile();
excelSheets = getSheetNames();
excelWorkSheet = (Excel.Worksheet)excelSheets.get_Item(2);
log.Debug("sheet Name: " + excelWorkSheet.Name);
connectToDb();
CloseExcelFile();
}
private void connectToDb()
{
int retVal = db.LoadSPVDataSheet(Properties.Settings.Default.importFilePath, this.fileName, excelWorkSheet.Name);
}
EDIT 2
I'm using SQL Server 2012 running on Windows Server 2012 R2
EDIT 3
I found the entry for AllowInProcess, and the Disallow Adhoc entry wasn't there. It was located #:
HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WOW6462Node\Microsoft\Microsoft SQL Server\MSAS11.<ServerName>\Providers\MSOLAP
I'm going add the entry and report back.
EDIT 4
The service code is now connecting and processing correctly. I found another place where theDisallowAdHocAccess registry key was missing.
HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WOW6462Node\Microsoft\Microsoft SQL Server\MSSQL11.<ServerName>\Providers\Microsoft.ACE.OLEDB.12.0
I added the key there, and it worked.

Check out this connect item: https://connect.microsoft.com/SQLServer/feedback/details/257494/smss-does-not-handle-the-provider-option-disallowadhocaccess-correctly
or read the detailes explained here: https://www.mssqltips.com/sqlservertip/4582/sql-server-ad-hoc-access-to-ole-db-provider-has-been-denied-error/
"We can disable "Disallow adhoc access" from the SSMS provider properties, but it removes the entry in the registry instead of changing the value to zero and we still get the ad hoc access to OLE DB provider has been denied error."
So you should manually add the missing entry in registry and enter 0 in it

Related

How to avoid connections against empty/null database by Entity Framework

We use entity framework to read from an existing database.
This is a simplified version of our code.
using (my context context = new mycontext())
{
if(context.Database.Connection.State == System.Data.ConnectionState.Closed)
{
_logger.Info(" Opening the connection to the database");
context.Database.Connection.Open();
}
context.Configuration.LazyLoadingEnabled = false;
IQueryable<mymodel> people;
people = context.People.OrderBy(x => x.Firstname);
_lstContacts = people.ToList();
if (context.Database.Connection.State != System.Data.ConnectionState.Closed)
{
context.Database.Connection.Close();
context.Database.Connection.Dispose();
_logger.Info(" Connection to the database Closed");
}
}
It works 100% of the time, but...
On our UAT environment we can see failed connections to the Microsoft SQL server with the error:
Login failed for user "my user". Reason: Failed to open the explicitly
specified database "null". Client my IP.
For us, these are ghost connections because at the time when we see the errors in the SQL server, our code is not executed.
Initially we didn't close and open the connection explicitly, we just added it trying to control when EF open and closes the connection, but it didn't fix the issue.
Our connection string is using the following format:
<add name="MYCN" connectionString="metadata=res://*/CVs.Cvs.csdl|res://*/CVs.Cvs.ssdl|res://*/CVs.Cvs.msl;provider=System.Data.SqlClient;provider connection string="data source=myserver\;initial catalog=mydatabase;Integrated Security=;User ID=myuser;Password=XXXXXXX;MultipleActiveResultSets=True;App=EntityFramework"/>
As you can see, we are specifying the database in the connection string and our user only have access to our database, so we understand the error when EF doesn't include the database in the connection string, but we don't understand why it's trying to perform these connections.
We know the connections are coming from our application, because we are the only one using that specific user, the IP is the IP of our server, and because the logs in SQL server tell us that the application is "EntityFramewrok"
I didn't personally see the error before, but researched for you and seen that many people suffered from the same problem discussed here: https://blogs.msdn.microsoft.com/sql_protocols/2006/02/21/understanding-login-failed-error-18456-error-messages-in-sql-server-2005/
I read all the messages in the website specified, and here are the solutions offered and at least one other user confirmed that it worked. You might not use 2005 as you didn't specify your version in your question, some solutions I believe will still work for you. Try the list below.
Solution list:
1) Please check the state number of this error and search solution by the state number in addition to the message, might give your more accurate solution proposals. Most common states are listed:
All state-error descriptions you can find here: https://sqlblog.org/2011/01/14/troubleshooting-error-18456
2) Make sure the username and password are correct.
3)
Logon to SQL Server using windows authentication.
Right click in the query window that appears and select "Open Server in Object Explorer"
Go to object explorer and open the "Security" folder and then the "Logins" folder.
Double-click the "sa" user and change the password. Also, like another user mentioned above, untick the "Enforce Password Policy" in
addition to resetting the password.
4) Try to change the password and turn off the policy, and try with new password.
exec sp_password #new = ‘sqlpassword’, #loginame = ‘sa’
alter login sa
with password = ‘sqlpassword’ unlock,
check_policy = off,
check_expiration = off
5) Run your application/browser and SSMS (if you work on it) in administration mode.
6)
Open Windows Services
Configure Microsoft Single Sign-on Service to use the proper account
Open Central Administration >> Operations >> Manage settings for single sign-on
Configure properties to use the same account used for Microsoft ‘Single Sign-on Service
7) Go to Sql server configuration manager and Enable TCP/IP and named pipes
8)
go to sql server
right click on server, choose properties
click on security
on server authentication, enable SQL Server authentication
These might help:
https://www.wikitechy.com/errors-and-fixes/sql/login-failed-error-18456-severity-14-state-38-reason-failed-to-open-the-explicitly-specified-database
https://dba.stackexchange.com/questions/90445/login-failed-for-user-error-18456-severity-14-state-38
I think this is just an access issue for myuser in the UAT environment. Just make sure myuser has access in the UAT environment for UAT database and you should be good.

Accessing MongoDB from a SQL Server 2008 CLR trigger

I'm using a SQL CLR trigger to push updates from the relational DB to a MongoDB instance. Both databases are running on the same Windows 2012 machine.
My SQL CLR project is built on .NET 3.5 and is using the mongocsharpdriver 1.10.0.
The C# code within my trigger is as follows:
SqlPipe pipe = SqlContext.Pipe;
pipe.Send("Begin ReportUpdateTrigger.VTProperty");
try
{
var settings = new MongoClientSettings();
settings.Server = new MongoServerAddress("127.0.0.1", 27017);
var client = new MongoClient(settings);
var server = client.GetServer();
var db = server.GetDatabase("VTProperty");
var coll = db.GetCollection<object>("Property");
var item = new { name = "test", datecreated = DateTime.Now };
coll.Insert(item);
}
catch (Exception ex)
{
pipe.Send("Error sending update to Reporting database: " + ex.Message);
}
pipe.Send("Done ReportUpdateTrigger.VTProperty");
(this is test code just to verify that the MongoDB operation will work).
I run the exact same code from a separate console app, and the data is posted to Mongo with no problems.
When running from the trigger, I see the following error:
Begin ReportUpdateTrigger.VTProperty Error sending update to Reporting
database: Unable to connect to server 127.0.0.1:27017: The type
initializer for 'MongoDB.Bson.Serialization.BsonSerializer' threw an
exception.. Done ReportUpdateTrigger.VTProperty
I have my DLL (and all supporting DLLs, including the MongoDB drivers) referenced as assemblies within the DB server. CLR is enabled. I know that the trigger is executing because I am getting the custom status and error messages in the SQL output window.
My hunch is that whatever user/process is executing the trigger code does not have access to the Mongo instance. Hence the "Unable to connect to server 127.0.0.1:27017" error. Not sure what my next step should be.
By default, SQLCLR external access has a security context of the service account (i.e. "Logon As" account) of the MSSQLSERVER service (or MSSQL$InstanceName, or something like that). And that service account, by default, is the Local System account. You can do one of two things here:
If your MSSQLSERVER service is using "Local System" as the account, then create a real local or domain / AD account and make that the service account. Then just make sure that the new real account has access to MongoDB.
Regardless of anything else, it is often best to have services such as SQL Server uses their own service accounts. That makes it easier to control and confine the permssions.
If you are using Windows logins, then you have the option of enabling Impersonation in the .NET code. When using Impersonation, the security context of external calls is set to the Windows Login that is executing the SQLCLR object.
For this, you would need to add something like the following to your code:
using System.Security.Principal;
// above the "try" block
WindowsImpersonationContext _ImpersonationIdentity = null;
// inside the "try", before anything else
_ImpersonationIdentity = SqlContext.WindowsIdentity.Impersonate();
// in a "finally" block
if (_ImpersonationIdentity != null)
{
_ImpersonationIdentity.Undo();
}

C# - Data source name not found and no default driver specified Exception Error

Good morning,
I am currently trying to use an ODBC connection to connect to my database.
private OdbcConnection connect = new OdbcConnection("DSN = My Data Source; DATABASE = MyDB;");
// From research I discovered that some people use DB instead of DATABASE.
After Googling the error, I found out that as the name specifies this occurs when there is no such name in the ODBC DSN connections. The problem could also arise when the application is looking for the 32-bit version, however, only the 64-bit version is setup. I went to System32 and SysWOW64, and made sure to setup a System DSN ODBC connection for each ODBCAD32 executable.
The error:
Any suggestions? Could it be that this is happening due to the fact that my DSN has spaces involved in the name? The DSN is properly setup due to the fact that it is being used by other software.
Thanks,
Isaac
OK so even though I set the user within the ODBC connection, I had to set the User ID and Password as such:
private OdbcConnection connect = new OdbcConnection("DSN=My Data Source; UID=User; PWD=Password;");
Also another issue was that I usually apply spaces surrounding the equal sign. This resulted in a connection error. Therefore do NOT do as below:
private OdbcConnection connect = new OdbcConnection("DSN = My Data Source; UID = User; PWD = Password;");
This error usually occur because of Insufficient Permissions to Read the DSN Registry Key
Grant the user account Read access to the specified ODBC System DSN registry key as follows:
Determine which account is used to process the request for the ASP page.
From the Start menu, click Run, type regedt32.exe, and then click OK to start Registry Editor.
In the HKEY_LOCAL_MACHINE window, browse to the HKLM\SOFTWARE\ODBC\ODBC.INI key. The ODBC.INI key contains a subkey for each ODBC SYSTEM DSN that is registered on the server.
Click the DSN registry key for the DSN that is specified in the ADO connection string.
From the Security menu, click Permissions.
Add the user account that you identified in step 1 to the list of users who can access this key, and select the Read check box for this user.
Click Apply, and then close Registry Editor.

Connect to database in network drive

I am a newbie to SQL Server and .net. Please let me know if my question is not clear before down voting.
I am working on a Windows application with C#. I should give option to users to connect to a .mdf file on a network drive. On my machine, I have Windows and SQL Server authentication. Users have SQL authentication hence I should use userid and pwd. Myself and users work on that network drive, read/write/modify. We pretty much share documents, add and delete docs from network drive.
Here is the designer
I will choose the SQL Server database .mdf file which is located in network drive and then do test connection. For Test Connection this is the code
string sTemp = System.Configuration.ConfigurationManager.AppSettings["connectionStringShare"];
string connectionString = sTemp.Replace("{AppDir}", txtDB.Text.Trim());
using (SqlConnection objSqlConnection = new SqlConnection(connectionString))
{
try
{
objSqlConnection.Open();
objSqlConnection.Close();
MessageBox.Show("Connection is successfull");
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.Message.ToString());
}
}
This is the connection string
<add key="connectionStringShare"
value="Data Source=.\SQLEXPRESS;Initial Catalog=TableSQLExpress;AttachDBFilename={AppDir};Integrated Security=SSPI;user id=sa;password=pwd;" />
Here is the error message I got
Directory lookup for the file "S:\zrep\TableSQLExpress.mdf" failed with the operating system error 3(The system cannot find the path specified.).
Cannot attach the file 'S:\zrep\TableSQLExpress.mdf' as database 'TableSQLExpress'.
I changed connection string and tried also tired using windows authentication. No luck. Let me know if I need to provide any additional details. Since I am newbie to this field please give me detailed answer. I am glad to find this group. Thanks for everyone who looked into this.
When you use server-based SQL Server (i.e. Microsoft SQL Server Express) you are unable to share database file via network drive, it is by design. Even if you override default SQL Server behavior with a switch and enable UNC paths for databases, your data will be corrupted by multiple server instances trying to use single database MDF file. If you need to host database in serverless environment (using only a network drive), you may opt to Microsoft SQL Server Compact (SQL Server CE) edition. But be aware that in such case only one user will be able to access database file at the same time (exclusive locking -> low performance). Plus SQL Server CE does not have stored procs.

Error attaching a database (.mdf file) to SQL Server

I'm having trouble attaching a database DBName.mdf to a network SQL Server. The admin can manually attach the database but if I try, I get the following error message.
Database 'DBName' cannot be upgraded because it is read-only, has read-only files or the user does not have permissions to modify some of the files. Make the database or files writeable, and rerun recovery. (Microsoft SQL Server, Error: 3415)
Here is my code:
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
conn.ConnectionString = #"Server=" + SQLServerName + ";database=master;User ID=" + UserName + ";Pwd=" + Password; ;
try
{
conn.Open();
System.Data.SqlClient.SqlCommand com = new System.Data.SqlClient.SqlCommand("CREATE DATABASE DBName ON ( FILENAME = '" + #"C:\DBName.mdf" + "' ), ( FILENAME = '" + #"C:\DBName_log.ldf" + "' ) FOR ATTACH", conn);
com.ExecuteScalar();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
Here is the details of SQL Server
- Product - Microsoft SQL Server Express Edition (64-bit)
- Version - 11.0.2218.0
I can create a new database just fine but cannot attach an existing database. What am I missing here?
Any help will be appreciated.
I figured out what the problem was.
This link was helpful in figuring out the problem.
http://www.sqlservercentral.com/Forums/FindPost1367859.aspx
The user under which the SQL Service was running didn't have full access permissions to that folder. I gave the user full permission and everything worked fine.
I had the same error trying to attach via SQL server management studio.
Running SQL server Management studio as Administrator solved this problem for me.
Info gleaned from here http://www.nickyvv.com/2013/02/database-databasename-cannot-be.html.
I also faced the similar problems and I resolved it using both approaches listed above by Butters and pblack. To sum up they are:
Go to the system services and find SQL Server Database service.
Right click on the service and select properties
Go to the Log On tab
If the "Log On As" user from your service is a user account, make sure that user account has Full Control on that folder.
If the "Log On As" user from your service is "Network Service" or "Local System" those account should already have access, but go ahead and add them and give them Full Control.
Lastly, RUN SQL Server management studio using Administrative privileges
I also faced similar situation while using T-SQL Script but i choose another way through SSMS. Here are some easy steps that are very helpful to you to attach SQL MDF file through SQL Server Management Studio.
Go through Start Button->All Programs->SQL Server XXXX->SQL Server Management Studio
Login in it
Select Object Explorer enlisted databases
Then Right click on it and Select Attach database
Database Attachment Windows appears on the Screen then click on ADD button
Then you need to select MDF file which you want to attach and click OK
Confirm it and Click OK
Database is successfully attached. You can checkout in the Databases list.

Categories

Resources