SQL Server & RStudio - SQL Connection Almost Working - sql

I've been running into an issue in R Studio with a SQL connection.
We've had an on-prem SQL Server that's been upgraded over the years, and a colleague that set it up no longer is with the organization.
We also have an Azure Server that's loaded with a SQL Server as well that was much more recently set up before they departed.
We have a GUI program we're currently developing, and one of the early steps is a SQL Login connection for the user where the variable is declared (db_user) and changes with their login and passes the password correctly within system variables defined in .Renviron as posted on RStudio's site for references.
Our initial connection string looks like this, and this is the line of code that starts the connection and where I believe the issue may lie first:
db_conn_onprem <- DBI::dbConnect(odbc::odbc(),
Driver = "SQL Server",
Server = Sys.getenv("server"),
Database = Sys.getenv("database"),
UID = Sys.getenv("db_user"),
PWD = Sys.getenv("PWD")
Whenever the Azure connection succeeds, it connects as dbo#Azure\Azure vs On-Prem's guest#Server\Server.
(I can't post in-line screenshots yet)
On-Prem Connection Screenshot: https://i.ibb.co/PmbGt5y/RStudio-SQL.png
Azure Connection Screenshot: https://i.ibb.co/WFY3FqZ/azure1.png
I feel this is something dbo-related since that's where the connection drops.
(variable names anonymized)
Now for the issue:
Whenever we attempt to run a series of queries, our on-prem errors out with this:
Error: nanodbc/nanodbc.cpp:1655: 42000: [Microsoft][SQL Server][SQL Server]Cannot execute as the server principal because the principal "db_user" does not exist, this type of principal cannot be impersonated, or you do not have permission.
<SQL> 'EXECUTE AS LOGIN = 'db_user' SELECT name FROM master.sys.sysdatabases WHERE dbid > 4 AND HAS_DBACCESS(name) = 1 ORDER BY name ASC'
However, run the exact same procedure on the SQL Server in Azure with relatively no major configuration, and it succeeds.
Here's the SQL Code we run:
EXECUTE AS LOGIN = 'db_user' SELECT name
FROM master.sys.sysdatabases
WHERE dbid > 4
AND HAS_DBACCESS(name) = 1
ORDER BY name ASC
I feel like I've exhausted my resources for this, first I thought it was the initial R code or possibly SQL Drivers, however I don't believe that to be the issue since the SQL driver pulls a list of names in R Studio in the Connections context menu, but bounces back the error when attempting to complete the query.
Whenever I'm searching errors for references for this error, I see
Cannot execute as the server principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.
Listed as the most commonly related error for the one I'm experiencing, however I've tried a number of those (From blank DB ownerships to unrelated solutions), but I've mostly hit a wall here.
Any assistance would be greatly appreciated.

I feel this is something dbo-related since that's where the connection drops, but I have no clue where to continue going on this issue.
Yep.
This
EXECUTE AS LOGIN = 'db_user'
requires impersonate permission for the login. Which the error message is clearly telling you. It's unclear why you want to impersonate that login instead of simply connecting as the login to begin with.

Related

How to prevent 'query timeout expired'? (SQLNCLI11 error '80040e31')

I have a connection to a MS SQL Server 2012 database in classic ASP (VBScript). This is my connection string:
Provider=SQL Server Native Client 11.0;Server=localhost;
Database=databank;Uid=myuser;Pwd=mypassword;
When I execute this SQL command:
UPDATE [info] SET [stamp]='2014-03-18 01:00:02',
[data]='12533 characters goes here',
[saved]='2014-03-18 01:00:00',
[confirmed]=0,[ip]=0,[mode]=3,[rebuild]=0,
[updated]=1,[findable]=0
WHERE [ID]=193246;
I get the following error:
Microsoft SQL Server Native Client 11.0
error '80040e31'
Query timeout expired
/functions.asp, line 476
The SQL query is pretty long, the data field is updated with 12533 characters. The ID column is indexed so finding the post with ID 193246 should be fast.
When I execute the exact same SQL expression (copied and pasted) on SQL Server Management Studio it completes successfully in no time. No problem what so ever. So there isn't a problem with the SQL itself. I've even tried using a ADODB.Recordset object and update via that (no self-written SQL) but I still get the same timeout error.
If I go to Tools > Options > Query Execution in the Management Studio I see that execution time-out is set to 0 (infinite). Under Tools > Options > Designers I see that transaction time-out is set to 30 seconds, which should be plenty enough since the script and database is on the same computer ("localhost" is in the connection string).
What is going on here? Why can I execute the SQL in the Management Studio but not in my ASP code?
Edit: Tried setting the 30 sec timeout in the Designers tab to 600 sec just to make sure, but I still get the same error (happens after 30 sec of page loading btw).
Here is the code that I use to execute the SQL on the ASP page:
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "Provider=SQL Server Native Client 11.0;
Server=localhost;Database=databank;Uid=myuser;Pwd=mypassword;"
Conn.Execute "UPDATE [info] SET [stamp]='2014-03-18 01:00:02',
[data]='12533 characters goes here',[saved]='2014-03-18 01:00:00',
[confirmed]=0,[ip]=0,[mode]=3,[rebuild]=0,[updated]=1,[findable]=0
WHERE [ID]=193246;"
Edit 2: Using Conn.CommandTimeout = 0 to give infinite execution time for the query does nothing, it just makes the query execute forever. Waited 25 min and it was still executing.
I then tried to separate the SQL into two SQL statements, the long data update in one and the other updates in the other. It still wouldn't update the long data field, just got timeout.
I tried this with two additional connection strings:
Driver={SQL Server};Server=localhost;Database=databank;Uid=myuser;Pwd=mypassword;
Driver={SQL Server Native Client 11.0};Server=localhost;Database=databank;Uid=myuser;Pwd=mypassword;
Didn't work. I even tried changing the data to 12533 A's just to see if the actual data was causing the problem. Nope, same problem.
Then I found out something interesting: I tried to execute the short SQL first, before the long update of the data field. It ALSO got query timeout exception...
But why? It has so little stuff to update in it (the whole SQL statement is less than 200 characters). Will investigate further.
Edit 3: I thought it might have been something to do with the login but I didn't find anything that looked wrong. I even tried changing the connection string to use the sa-account but even that didn't work, still getting "Query timeout expired".
This is driving me mad. There is no solution, no workaround and worst of all no ideas!
Edit 4: Went to Tools > Options > Designers in the Management Studio and ticked off the "Prevent saving changes that require table re-creation". It did nothing.
Tried changing the "data" column data type from "nvarchar(MAX)" to the inferior "ntext" type (I'm getting desperate). It didn't work.
Tried executing the smallest change on the post I could think of:
UPDATE [info] SET [confirmed]=0 WHERE [ID]=193246;
That would set a bit column to false. Didn't work. I tried executing the exact same query in the Management Studio and it worked flawlessly.
Throw me some ideas if you have got them because I'm running out for real now.
Edit 5: Have now also tried the following connection string:
Provider=SQLOLEDB.1;Password=mypassword;Persist Security Info=True;User ID=myuser;Initial Catalog=databank;Data Source=localhost
Didn't work. Only tried to set confirmed to false but still got a time out.
Edit 6: Have now attempted to update a different post in the same table:
UPDATE [info] SET [confirmed]=0 WHERE [ID]=1;
It also gave the timeout error. So now we know it isn't post specific.
I am able to update posts in other tables in the same "databank" database via ASP. I can also update tables in other databases on localhost.
Could there be something broken with the [info] table? I used the MS Access wizard to auto move data from Access to MS SQL Server 2012, it created columns of data type "ntext" and I manually went and changed that to "nvarchar(MAX)" since ntext is deprecated. Could something have broken down? It did require me to re-create the table when I changed the data type.
I have to get some sleep but I will be sure to check back tomorrow if anybody has responded to me. Please do, even if you only have something encouraging to say.
Edit 7: Quick edit before bed. Tried to define the provider as "SQLNCLI11" in the connection string as well (using the DLL name instead of the actual provider name). It makes no difference. Connection is created just as fine but the timeout still happens.
Also I'm not using MS SQL Server 2012 Express (as far as I know, "Express" wasn't mentioned anywhere during installation). It's the full thing.
If it helps, here's the "Help" > "About..." info that is given by the Management Studio:
Microsoft SQL Server Management Studio: 11.0.2100.60
Microsoft Analysis Services Client Tools: 11.0.2100.60
Microsoft Data Access Components (MDAC): 6.3.9600.16384
Microsoft MSXML: 3.0 5.0 6.0
Microsoft Internet Explorer: 9.11.9600.16521
Microsoft .NET Framework: 4.0.30319.34011
Operating System: 6.3.9600
Edit 8 (also known as the "programmers never sleep" edit):
After trying some things I eventually tried to close the database connection and reopening it right before executing the SQL statements. It worked all of a sudden. What the...?
I have had my code inside a subroutine and it turns out that outside of it the post that I was trying to update was already opened! So the reason for the timeout was that the post or the whole table was locked by the very same connection that tried to update it. So the connection (or CPU thread) was waiting for a lock that would never unlock.
Hate it when it turns out to be so simple after trying so hard.
The post had been opened outside the subroutine by this simple code:
Set RecSet = Conn.Execute("SELECT etc")
I just added the following before calling the subroutine.
RecSet.Close
Set RecSet = Nothing
The reason why this never crossed my mind is simply because this was allowed in MS Access but now I have changed to MS SQL Server and it wasn't so kind (or sloppy, rather). The created RecSet by Conn.Execute() had never created a locked post in the database before but now all of a sudden it did. Not too strange since the connection string and the actual database had changed.
I hope this post saves someone else some headache if you are migrating from MS Access to MS SQL Server. Though I can't imagine there are that many Access users left in the world nowadays.
Turns out that the post (or rather the whole table) was locked by the very same connection that I tried to update the post with.
I had a opened record set of the post that was created by:
Set RecSet = Conn.Execute()
This type of recordset is supposed to be read-only and when I was using MS Access as database it did not lock anything. But apparently this type of record set did lock something on MS SQL Server 2012 because when I added these lines of code before executing the UPDATE SQL statement...
RecSet.Close
Set RecSet = Nothing
...everything worked just fine.
So bottom line is to be careful with opened record sets - even if they are read-only they could lock your table from updates.

Problem creating database using SQL Server Management Express

I am trying to create a database using SQL Server Management Express.
The following error occurs:
TITLE: Microsoft SQL Server Management
Studio Express
Create failed for Database
'dbTestDBase'.
(Microsoft.SqlServer.Express.Smo)
For help, click:
http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=9.00.2047.00&EvtSrc=Microsoft.SqlServer.Management.Smo.ExceptionTemplates.FailedOperationExceptionText&EvtID=Create+Database&LinkId=20476
ADDITIONAL INFORMATION:
An exception occurred while executing
a Transact-SQL statement or batch.
(Microsoft.SqlServer.Express.ConnectionInfo)
CREATE DATABASE permission denied in
database 'master'. (Microsoft SQL
Server, Error: 262)
For help, click:
http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=09.00.1399&EvtSrc=MSSQLServer&EvtID=262&LinkId=20476
Run Microsft SQL Server Studio as administrator....your problem will be solved
It's very clear: the credential you are using doesn't have enough privileges to be able to create a new database. Are you logged in using Integrated Windows Authentication or Sql Server Authentication? Make sure your credentials have the dbcreator role either way.
http://msdn.microsoft.com/en-us/library/ms176014%28v=SQL.90%29.aspx
If the computer is part of Domain. Log-in as local administrator account on the work station (maybe because the MSQSQL is installed on the computer using local administrator account, means that the local administrator account has systemadmin access on SMSQL), then when you are already logged as local administrator. open the MSSQL , now add/edit MSSQL security account.
I had this same problem. but solved!
you should go to your specify folder where database created (ex:C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA)
then right click on data folder -> properties-> advanced
then uncheck compress content to save disk space.
that's it.
Well, the error message seems to be pretty clear:
CREATE DATABASE permission denied in
database 'master'.
Obviously, the user account you're using doesn't have the permission to create a new database. Is that possible? What kind of user are you using?
Also: can you show us the CREATE DATABASE statement you're using??
Just check whether path is specified or not
For example : "C:..\MSSQL\DATA", in both the columns of Database files in the New Database wizard
I hope this solution will help someone!
My problem started when I had deleted the previous user from PC Management and from registry. Then I create a fresh-std user. and trying to create database from the new user, and that's where my problem started.
After searching for the better solution, I conclude by Uninstalling MS Server Express Database completely from my PC and re-install it again. This save time and solved my problem.
I hope this solution helps someone too!
I had similar issue and was solved by executing below command
--Step1 Find if it is used by some other PID
Use
master
GO
IF
EXISTS(SELECT request_session_id FROM
sys.dm_tran_locks
WHERE resource_database_id =
DB_ID('Model'))
PRINT
'Model Database being used by some other session'
ELSE
PRINT
'Model Database not used by other session'
-- Step 2 - Identify
SELECT request_session_id FROM
sys.dm_tran_locks
-- Step 3 Get PID
WHERE resource_database_id =
DB_ID('Model')
-- Step 4 Get the EventInfo
DBCC InputBuffer(214)
-- Step 5 Kill the PID
Kill 214
Hope this helps
I had the same problem when trying to create the database with Right Click + New Database on Databases.
The solve was using New Query and the command to create database:
CREATE DATABASE databasename;
In the end I want to mention that I was logged in Management Studio with (localdb)\v11.0 over windows authentication.

Linked servers SQLNCLI problem. "No transaction is active"

Im trying to execute a stored procedure and simply insert its results in a temporary table, and I'm getting the following message:
The operation could not be performed because OLE DB provider "SQLNCLI"
for linked server "MyServerName" was unable to begin a distributed
transaction. OLE DB provider "SQLNCLI" for linked server
"MyServerName" returned message "No transaction is active.".
My query looks like this:
INSERT INTO #TABLE
EXEC MyServerName.MyDatabase.dbo.MyStoredProcedure Param1, Param2, Param3
Exact column number, names, the problem is not the result.
MSDTC is allowed and started in both computers, Remote procedure calling too.
The machines are not in the same domain, but I can execute remote queries from my machine and get the result. I can even execute the stored procedure and see its results, I just can't insert it in another table.
EDIT
Oh I forgot to mention, the stored procedure doesn't fire any trigger. It only inserts records in temporary tables which it creates itself for data treating.
Well, after following lots of tutorials and researching a lot about it, I had changed all the configuration I thought was necessary for it to work, but it still didn't.
Today we had to force a power reboot on our development server because of a faulty no-break, and when we booted up the server, guess what? It works!
So just for the record, I've changed some specific MSDTC configuration, added it as a linked server and allowed RPC IN and OUT, and changed the RPC configuration for 'NO AUTHENTICATION REQUIRED' or something like that.
I remember reading somewhere that after you changed this configuration, a reboot was required, even though Windows says that it has already restarted the service.
I had rebooted my server like... twice since I changed it, and it still didn't work. But as today, after a complete turn off and turn on, it works!
As for the syntax, I kept the same.
You also have to check the DNS name resolution in the IP network configuration.
For example, you have a server called server-a.mydomain.com and another one called server-b.otherdomain.com, log in the server-a and do a "ping server-b" (without the domain).
If it responds "Ping request could not find host server-b. Please check the name and try again." that is the problem.
Go to the Control Pannel > Network Connections > Right click in the network card > properties > Internet Protocol > Properties > Advanced > DNS > Append this DNS suffix in order.
And here add the local domain: mydomain.com and then add the remote domain: otherdomain.com
Click OK until you exit
Now if you do the "ping server-b" it should repond something like:
Pinging server-b.otherdomain.com [192.168.1.2] with 32 bytes of data:
Reply from 192.168.1.2: bytes=32 time=12ms TTL=64 Reply from
192.168.1.2: bytes=32 time=9ms TTL=64
Now try to again to execute the distributed transaction.
I had the luxury of safely restarting the SQL Server services on both sides of the Linked Server connection. I did not have to reboot the machines.
Have you tried using openquery?
insert into table select * from openquery(myservername, 'exec mydatabase.dbo.mystoredproc param1, param2, param3')

how to access sql server from asp page

We have a legacy, homegrown timesheet system (ASP, microsoft sql server 2005) that I need to clone to another computer for backup purposes. (I know very little about this stuff, so pleas be gentle)
I've got most of the pieces in place (IIS, Sql Server, table import / creation). But, the ASP page to access the timesheet pages is choking on access to the sql server.
here is the line it's crashing on: conn.open Session("sConnStr")
This is the connection string;
sConnStr = "Server=MYSERVER-D01;DATABASE=MYDATABASE;UID=MyDatabaseUser;PWD=MyDatabaseUser;QuotedID=No;DRIVER={SQL Server};Provider=MSDASQL"
This is the error:
Error Type: Microsoft OLE DB Provider for ODBC Drivers (0x80004005) [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified /mydir/mypage.asp, line 17 <== shown above
Note that am able to access the db on SQL Server with Windows specified as the authentication using Server Management Studio. However, when i try using SQL Authentication, I get the message "The user is not associated with a trusted SQL connection".
Questions:
How do you set up the user / password on SQL Server 2005?
What is the default driver, and do i need to get it/set it up?
When it talks about the data source name ( see "MYDATABASE" in the
above mentioned connection string), is it talking about one of the
entries you see under "Databases" on the management studio object
explorer?
Thanks for you responses! So far, no luck. I've managed to access the database via management studio object explorer, by doing this;
Enable SQL Authentication:
....Solution
To resolve this issue, follow the instructions to set User Authentication.
SQL Server 2000:
Go to Start > Programs > Microsoft SQL Server > Enterprise Manager
Right-click the Server name, select Properties > Security
Under Authentication, select SQL Server and Windows
The server must be stopped and re-started before this will take effect
SQL Server 2005:
Go to Start > Programs > Microsoft SQL Server 2005 > SQL Server Management Studio
Right-click the Server name, select Properties > Security
Under Server Authentication, select SQL Server and Windows Authentication Mode
The server must be stopped and re-started before this will take effect..."
And
this;
Change the owner to the one being used to access the db
Microsoft SQL Server Management Studio
Right click the DB, change the owner
But I'm still getting exactly the same error message!
To create a new user and assign it to a database you'll need to do the following,
In SQL Server Management Studio, open Object Explorer and expand the
folder of the server instance in which
to create the new login.
Right-click the Security folder, point to New, and then click Login.
On the General page, enter a name for the new login in the Login name
box.
Select SQL Server Authentication. Windows Authentication is the more
secure option.
Enter a password for the login.
Select the password policy options that should be applied to the new
login. In general, enforcing password
policy is the more secure option.
Click OK.
You will then want to assign that login to a database by creating a new database user,
In SQL Server Management Studio, open Object Explorer and expand the
Databases folder.
Expand the database in which to create the new database user.
Right-click the Security folder, point to New, and then click User.
On the General page, enter a name for the new user in the User name box.
In the Login name box, enter the name of a SQL Server login to map to
the database user.
Click OK.
You'll want to make that user the db_owner. Run the following against your database.
sp_addrolemember #rolename = 'db_owner', #membername = 'usernamehere'
Then use the following connection string format to connect to the database.
Data Source=ServerAddress;Initial Catalog=DatabaseName;User Id=UserName;Password=UserPassword;
If you have a trusted connection from the login that IIS is using the the machine that has SQL Server running on it I would avoid using Username / Password and declare that the connection is trusted in your connection string:
sConnStr = "Server=MYSERVER-D01;DATABASE=MYDATABASE;UID=MyDatabaseUser;PWD=MyDatabaseUser;QuotedID=No;DRIVER={SQL Server};Provider=MSDASQL;Integrated Security=SSPI"
This is to illustrate the change, but in practice you may need to vary the connections string a bit more than that, have a look at http://www.connectionstrings.com/sql-server-2005 for examples.
When it talks about the data source name ( see "MYDATABASE" in the above mentioned connection string), is it talking about one of the entries you see under "Databases" on the management studio object explorer
Yes, your entry for "MYDATABASE" should be the exact name of the database that you see under "Databases". Make sure that you have the "Server" correct too.
Microsoft OLE DB Provider for ODBC Drivers error '80004005'
[Microsoft][ODBC Driver Manager]Data source name not found and no default driver specified.
This usually happens in one of the following scenarios:
* you referenced your connection incorrectly (e.g. spelled the DSN name, or one of the DSN-less string components wrong);
* you referenced a DSN that doesn't exist;
* the user connecting to the DSN or DSN-less connection doesn't have access to the information stored in the registry (see KB #306345);
* you used an English or localized driver detail for your connection string when your system is not set up in that language (see KB #174655); or,
* you are missing the connection string entirely (this can happen if you maintain your connection string in a session variable, and your sessions aren't working; see Article #2157).
Here is the link to the above article (note it is extremely detailed).
link
To answer the last question, MYDATABASE is calling a database by name. If you use 'MYDATABASE' in your string, you will need a database named 'MYDATABASE' in SQL Server.
This connection string should work fine with ASP if this is a SQL server. Replace your values before using obviously.
sConnStr = "provider=SQLOLEDB;Data Source=YourServerName;Initial Catalog=YourDBName;UID=YourUserName;PWD=YourUserPWD;"
The easiest way I have found to deal with these issue is to create a udl file. On your desktop create a new text file and rename it filename.udl. Double click the udl file. Click the Provider Tab > select Microsoft OLE DB Provider for SQL Server > Next. Using the connection tab you should be able to connect to your database. Once test connection succeeds click ok. You can now open the file in a text editor and copy and paste the line that start Provider... to your asp file. You should end up with sConnStr = "Provider..textfromUDLfile"
MSDN - Creating and Configuring Universal Data Link (.udl) Files
I suggest that you create a DAL (Data Access Layer) that can do all the connection stuff for you. Just passit your command an dit can open and close your conenctions and such. In any app you wan tto abstract these different layers as much as posible and that means that your aspx page should call to an object when has the methods that hten get handled by the dal and make the database calls.
Here is the format for connection to the DB. You can put the connecitn string in the web.config file or even do it in code using hte connectionstringbuilder.
you also need to make sure that your project includes the system.data.sqlclient library otherwise this won't work.
The entry in the web config file looks something like this.
<add name="ConString" connectionString="Data Source=localhost;Integrated Security=True;Initial Catalog="DBtouse";Persist Security Info=True;" providerName="System.Data.SqlClient"/>
or
<add key="ConString" value="Server=localhost;user=username;password=password;Initial Catalog=MyDBtouse;pooling=false"/>
the code behind loks like this:
Dim MyConnection As Data.SqlClient.SqlConnection
Dim Constring As New SqlClient.SqlConnectionStringBuilder
Constring.ConnectionString = System.Configuration.ConfigurationSettings.AppSettings("ConString")
Constring.ConnectTimeout = 30
MyConnection.ConnectionString = Constring.ConnectionString
MyConnection.Open()
'Execute code here
MyConnection.Close()
MyConnection = Nothing

SQL 2005 Linked Server Query Periodically Failing

We have a database running on SQL 2005. One of the store procedure looks up a user's email address from Active Directory using a linked server. The call to the linked server occurs in a database function.
I'm able to call is successfully from my Asp.Net application the first time, but periodically after that, it fails with the following error:
{"The requested operation could not be performed because OLE DB provider \"ADsDSOObject\" for linked server \"ADSI\" does not support the required transaction interface."}
It appears that the amount of time between calling the function affects whether the linked server query will work correctly. I am not using any transactions. When I try calling the function in a quick make-shift SQL script, it runs fine everytime (even when tested in quick succession).
Is there some sort of transaction being left open that naturally dies if I don't try calling the procedure again? I'm at a loss here.
Here is the simple call in the store procedure:
DECLARE #email varchar(50)
SELECT #email = LEFT(mail, 50)
FROM OPENQUERY (
ADSI,
'SELECT mail, sAMAccountName FROM ''LDAP://DC=Katz,DC=COM'' WHERE objectCategory = ''Person'' AND objectClass = ''User'''
)
WHERE sAMAccountName = CAST(#LoginName AS varchar(35))
RETURN #email
I've worked with SQL Server linkservers often, though rarely LDAP queries... but I got curious and read the Microsoft support page linked to in Ric Tokyo's previous post. Towards the bottom it reads:
It is typical for a directory server
to enforce a server limitation on the
number of objects that will be
returned for a given query. This is to
prevent denial-of-service attacks and
network overloading. To properly query
the directory server, large queries
should be broken up into many smaller
ones. One way to do this is through a
process called paging. While paging is
available through ADSI's OLEDB
provider, there is currently no way
available to perform it from a SQL
distributed query. This means that the
total number of objects that can be
returned for a query is the server
limit. In the Windows 2000 Active
Directory, the default server limit is
1,000 objects.
I'm thinking that the reason it fails on you (or not) depending on whether call it from the app or from a "quick make-shift sql script" (as you put it) might be related to the security context under which the operation is executing. Depending on how the link server connection was set up, the operation could be being executed under a variety of possible credentials depending on how you initiate the query.
I don't know, but that's my best guess. I'd look at the linkserver configuration, in particular the linkserver settings for what set of credentials are used as the security context under which operations executed across the linkserver run.
Rather then query Active Directory through a linked server, you might be better off caching your AD data into a SQL database and then querying that instead. You could use Integration Services by creating a OLE DB connection using "OLE DB PRovider for Microsoft Directory Services" and having a DataReader source with a query like:
SELECT physicalDeliveryOfficeName, department, company, title, displayName, SN,
givenName, sAMAccountName, manager, mail, telephoneNumber, mobile
FROM 'LDAP://DC=SOMECO,DC=COM'
WHERE objectClass='User' and objectCategory = 'Person'
order by mail
Using this method you will still run into the 1000 row limit for results from an AD query (note it is NOT advisable to try and increase this limit in AD, it is there to prevent the domain controller from becoming overloaded). Sometimes its possible to use a combination of queries to return the full data set, e.g. names A - L and M - Z
Alternatively you could use the CSVDE command line utility in Windows Server to export your directory information to a CSV file and then import it into a SQL database (see http://computerperformance.co.uk/Logon/Logon_CSVDE_Export.htm for more info on exporting AD data with CSVDE).
please read the support page from Microsoft
I suspect that it might be the cached query plan due to your statement that "When I try calling the function in a quick make-shift SQL script, it runs fine everytime (even when tested in quick succession)."
Could you try executing your stored procedure like so:
EXEC usp_MyProcedure WITH RECOMPILE
This question appears in the top of the first google page when search for the error string but has not valid answer.
This error happens intermitently when isolation level is not specified on .NET code nor in Store Procedure.
This error also happens in SQL Server 2008.
The fix is force SET TRANSACTION ISOLATION LEVEL READ (UN)COMMITTED because a isolation level any higher is not supported by Active Directory and SQL Server is trying to use SERIALIZABLE.
Now, as this error is intermitent. Why is ADO.NET or SQLServer switching its default isolation to SERIALIZABLE sometimes and sometimes not? What triggers this switching?