Showing posts with label adp. Show all posts
Showing posts with label adp. Show all posts

Sunday, March 25, 2012

Access Data Projects Uniqueidentifier problem

Hi,

I am designing a SQL server backend, MS Access (ADP) frontend
application and I came across an interesting problem.
Lets say I have a table T with the following fields(columns)
[a] (int Not Null, Primary key, Identity auto increment)
[b] (uniqueidentifier, Allow Nulls)
[c] (text)

When I open the table in datasheet view using Access and type a value
in [c], [a] and [b] get populated automatically. [a] getting filled
with incremental integers is understandable. But, I have not set the
ISRowGUID or a default value for [b] and still it gets popullated with
a random GUID. If I use SQL Server enterprise manager to enter data
into the table T, [b] does not get filled and stays Null. I forgot to
mention that there are no relationships between the tables yet.
Is it MS access that is responsible or is it me? In any case can
something be dont to prevent this? Also should there be something else
in relation to this that I have to look for in the future.

My best
Ibrahim MMSSQL itself won't put in a value unless you have a column default or a
trigger on the table, so it seems likely that Access is doing this. You
could use Profiler to see exactly what commands Access sends to the
server when you use the datasheet, but if you want to know why it does
that, then I guess you'll get a better answer in an Access group.

Simon|||Thanks Simon,

The "problem" in fact does lie in MS Access.

I found a fix here
http://www.developersdex.com/sql/me...p=581&r=3822184

Thanks a lot for all the help !
My best
Ibrahim M

Access ComboBox Wont Populate

I'm using SQLServer2000/Access 2000 .adp. The .adp has a form with 2 combo boxes. The 1st combo box is bound to a stored procedure and loads fine when the form loads. I then set the 2nd combo box's RowSource passing the value of the first into the stored proc:

Me.secondComboBox.RowSource = "EXEC dbo.proc_My2ndProc '" & Me.cboFirstComboBox & "'"
Me.cbosecondComboBox.reQuery

Why won't it work? I've set a form's RecordSource using this methof, and it works great?

Thanks,
CarlDummy me, I didn't have the RowSourceType set to Table/View/StoredProc, all's well. I figured it out by creating a new form, and it was working, so I went to see what was different.

Thursday, March 22, 2012

Access and extended properties

Hello,
Can I read and write the extended properties with Access?


If it’s possible is better create a project (ADP) or a classic MDB?

When I try with this query in the query panel (in a MDB)

SELECT objtype, objname, name, value
FROM fn_listextendedproperty
(NULL, 'schema', 'Person', 'table', default, NULL, NULL)

I have this error message:

The size of a field is too long

If I try with an ADP, when I ask a new query in design view, I have a message for some roblems between the Access version (2003) and SQL Server version (2005) and I can’t save the query.

Tanks.

Hi,

yes - there's no support for SQL Server 2005 in an Access 2003 ADP (you cant save tables, ,,,). If you have this combination it would be better to make a mdb file with odbc connection.... access 2007 supports sql server 2005 more or less...

if you create a mdb you can execute your sql query with ado or pt querys...

regards

audi

Access and extended properties

Hello,
Can I read and write the extended properties with Access?


If it’s possible is better create a project (ADP) or a classic MDB?

When I try with this query in the query panel (in a MDB)

SELECT objtype, objname, name, value
FROM fn_listextendedproperty
(NULL, 'schema', 'Person', 'table', default, NULL, NULL)

I have this error message:

The size of a field is too long

If I try with an ADP, when I ask a new query in design view, I have a message for some roblems between the Access version (2003) and SQL Server version (2005) and I can’t save the query.

Tanks.

Hi,

yes - there's no support for SQL Server 2005 in an Access 2003 ADP (you cant save tables, ,,,). If you have this combination it would be better to make a mdb file with odbc connection.... access 2007 supports sql server 2005 more or less...

if you create a mdb you can execute your sql query with ado or pt querys...

regards

audi

Access ADP,Server 2000, inconsistent behavior with output paramete

I am getting inconsistent responses from SQL Server 2000 and do not know why
.
I populate the controls on an unbound form by executing a command object tha
t
calls a sproc that returns a recordset.
On SQL Server 2000 the srpoc returns the recordset used to fill the form's
controls plus an output parameter indicating a record was received. The
output parameter is the value of @.@.ROWCOUNT. If the value of the output
parameter = 0, the user gets an appropriate message concerning the failure t
o
retrieve the data.
The server on my desktop returns both the recordset for populating the form
and the value of @.@.ROWCOUNT from the database. No problem.
However, when I connect to an identical dataase on a server in Chicago using
a VPN, all I get back is the recordset. The value of the output parameter is
always zero, telling me no record was selected.
However, the record was selected as the data populates the form.
I can easily branch to the needed message using "If rst.BOF and rst.EOF
then..." but I'd like to know why the output parameter does not get returned
or is always zero when I use the VPN to connect to the database.
If I use a command object to execute a sproc that does not return a
recordset, I do get back any desired output parameters. This inconsistent
behavior only appears when the executed command object returns a recordset.
Is there a setting on the Chicago server causing the problem?
malcolmHow are you sure that these two databases are really identical?
One possibility would be that the server in Chicago has a different order
for fields inside a table. This could cause some trouble with ADP is you are
using things like Select * instead of Select field1, field2, ... .
When you change the connection, the Tables and the Views/SP/Functions
windows should be refreshed but we never know what may have happened. One
way to be sure would be to use the Refresh command for *BOTH* the Tables and
the Views/SP/Functions windows and/or to recompile the ADP file.
Another possibility would be a permission problem or a logon account that is
not mapped to the same role.
Sylvain Lafontaine, ing.
MVP - Technologies Virtual-PC
E-mail: http://cerbermail.com/?QugbLEWINF
"malcolm" <ramartower@.access312.com> wrote in message
news:00FCB54F-AEA4-43EB-A712-3B6FC3B68DA5@.microsoft.com...
>I am getting inconsistent responses from SQL Server 2000 and do not know
>why.
> I populate the controls on an unbound form by executing a command object
> that
> calls a sproc that returns a recordset.
> On SQL Server 2000 the srpoc returns the recordset used to fill the form's
> controls plus an output parameter indicating a record was received. The
> output parameter is the value of @.@.ROWCOUNT. If the value of the output
> parameter = 0, the user gets an appropriate message concerning the failure
> to
> retrieve the data.
> The server on my desktop returns both the recordset for populating the
> form
> and the value of @.@.ROWCOUNT from the database. No problem.
> However, when I connect to an identical dataase on a server in Chicago
> using
> a VPN, all I get back is the recordset. The value of the output parameter
> is
> always zero, telling me no record was selected.
> However, the record was selected as the data populates the form.
> I can easily branch to the needed message using "If rst.BOF and rst.EOF
> then..." but I'd like to know why the output parameter does not get
> returned
> or is always zero when I use the VPN to connect to the database.
> If I use a command object to execute a sproc that does not return a
> recordset, I do get back any desired output parameters. This inconsistent
> behavior only appears when the executed command object returns a
> recordset.
> Is there a setting on the Chicago server causing the problem?
> --
> malcolm

ACCESS ADP TransferSpreadsheet

Ok...here's a good one.

I wrote an ADP application in ACCESS XP with a SQL 2000 back end.
Works Great! Recently we did a server migration and transfered the
database to another server. Setup all the groups and security without
a hitch. My users change the Connection to point to the new server and

all of a sudden the TransferSpreadsheet function that I'm using in two
seperate procedures starts to error saying that it can't see the table.

So I look...and there it is. The function doesn't see it though.

I try it on my machine and it works fine, but I have Local Admin rights

on the server though. So we start looking around. What we found is
that only those with Local Admin Rights and Server Administration
rights seem to be able to execute the procedure so that the
TransferSpreadsheet works correctly.

Initially I thought that it maybe the way the Server is configured, so
we moved it to another location and tried it again with no luck. Tried

putting it back on the original server and again, it works great!
We've used SQL Compair to make sure that something didn't get changed
in the process, and everything looks ok. I will admit that there may
have been something in the way that the first server was configured,
but it doesn't explaine why the function isn't working correctly now.

All the machines that I tried it on are using the following:

Desktops:
XP Professional w/SP 1 or 2
ACCESS XP
MDAC 2.8

Servers:
Windows 2003 Server w/SP1
SQL Server 2000 w/SP4
or
SQL Server 2005 w/SP1 - We've tried both.

If anyone has any Idea's, I'm open.

Thank for your time.Hi, Dave

I have encountered the same problem in a similar configuration (Access
XP Full/Runtime, MSDE 2000 SP3/SP4, TransferDatabase function). The
issue seems to be caused by the fact that MS Access looks for a
qualified table name, using the prefix given by the username of the
current connection. In other words, if the connection is using a login
that is member of the sysadmin server role or is db_owner for the
database, then it looks for the dbo.tablename. If the login corresponds
to a particular user in that database, it looks for the
username.tablename table.

Razvan

Dave wrote:

Quote:

Originally Posted by

Ok...here's a good one.
I wrote an ADP application in ACCESS XP with a SQL 2000 back end.
Works Great! Recently we did a server migration and transfered the
database to another server. Setup all the groups and security without
a hitch. My users change the Connection to point to the new server and
all of a sudden the TransferSpreadsheet function that I'm using in two
seperate procedures starts to error saying that it can't see the table.
So I look...and there it is. The function doesn't see it though.
>
I try it on my machine and it works fine, but I have Local Admin rights
on the server though. So we start looking around. What we found is
that only those with Local Admin Rights and Server Administration
rights seem to be able to execute the procedure so that the
TransferSpreadsheet works correctly.
>
Initially I thought that it maybe the way the Server is configured, so
we moved it to another location and tried it again with no luck. Tried
putting it back on the original server and again, it works great!
We've used SQL Compair to make sure that something didn't get changed
in the process, and everything looks ok. I will admit that there may
have been something in the way that the first server was configured,
but it doesn't explaine why the function isn't working correctly now.
>
All the machines that I tried it on are using the following:
>
Desktops:
XP Professional w/SP 1 or 2
ACCESS XP
MDAC 2.8
>
Servers:
Windows 2003 Server w/SP1
SQL Server 2000 w/SP4
or
SQL Server 2005 w/SP1 - We've tried both.
>
If anyone has any Idea's, I'm open.
>
Thank for your time.

|||Razvan...Thanks for the reply. I must have left that part out. Sorry.
I did try including dbo.TableName. That also doesn't work. Onething
that I've been talking over with coworkers is Office Versions. The
Test User account that I used, I also used on an Office 2k3 machine.
Everyone else is either using XP or 2K. I know that that shouldn't be
an issue, but right now that's the only thing that's different.

I have to try the Test User account on an XP or 2K machine.

Razvan Socol wrote:

Quote:

Originally Posted by

Hi, Dave
>
I have encountered the same problem in a similar configuration (Access
XP Full/Runtime, MSDE 2000 SP3/SP4, TransferDatabase function). The
issue seems to be caused by the fact that MS Access looks for a
qualified table name, using the prefix given by the username of the
current connection. In other words, if the connection is using a login
that is member of the sysadmin server role or is db_owner for the
database, then it looks for the dbo.tablename. If the login corresponds
to a particular user in that database, it looks for the
username.tablename table.
>
Razvan
>
Dave wrote:

Quote:

Originally Posted by

Ok...here's a good one.

I wrote an ADP application in ACCESS XP with a SQL 2000 back end.
Works Great! Recently we did a server migration and transfered the
database to another server. Setup all the groups and security without
a hitch. My users change the Connection to point to the new server and

all of a sudden the TransferSpreadsheet function that I'm using in two
seperate procedures starts to error saying that it can't see the table.

So I look...and there it is. The function doesn't see it though.

I try it on my machine and it works fine, but I have Local Admin rights

on the server though. So we start looking around. What we found is
that only those with Local Admin Rights and Server Administration
rights seem to be able to execute the procedure so that the
TransferSpreadsheet works correctly.

Initially I thought that it maybe the way the Server is configured, so
we moved it to another location and tried it again with no luck. Tried

putting it back on the original server and again, it works great!
We've used SQL Compair to make sure that something didn't get changed
in the process, and everything looks ok. I will admit that there may
have been something in the way that the first server was configured,
but it doesn't explaine why the function isn't working correctly now.

All the machines that I tried it on are using the following:

Desktops:
XP Professional w/SP 1 or 2
ACCESS XP
MDAC 2.8

Servers:
Windows 2003 Server w/SP1
SQL Server 2000 w/SP4
or
SQL Server 2005 w/SP1 - We've tried both.

If anyone has any Idea's, I'm open.

Thank for your time.

|||it has something to with Access not being able to see the fully
qualified table name correctly.
i have not found a fix except to run a stored proc that changes the
object owner on the database.

Dave wrote:

Quote:

Originally Posted by

Razvan...Thanks for the reply. I must have left that part out. Sorry.
I did try including dbo.TableName. That also doesn't work. Onething
that I've been talking over with coworkers is Office Versions. The
Test User account that I used, I also used on an Office 2k3 machine.
Everyone else is either using XP or 2K. I know that that shouldn't be
an issue, but right now that's the only thing that's different.
>
I have to try the Test User account on an XP or 2K machine.
>
>
>
>
Razvan Socol wrote:

Quote:

Originally Posted by

Hi, Dave

I have encountered the same problem in a similar configuration (Access
XP Full/Runtime, MSDE 2000 SP3/SP4, TransferDatabase function). The
issue seems to be caused by the fact that MS Access looks for a
qualified table name, using the prefix given by the username of the
current connection. In other words, if the connection is using a login
that is member of the sysadmin server role or is db_owner for the
database, then it looks for the dbo.tablename. If the login corresponds
to a particular user in that database, it looks for the
username.tablename table.

Razvan

Dave wrote:

Quote:

Originally Posted by

Ok...here's a good one.
>
I wrote an ADP application in ACCESS XP with a SQL 2000 back end.
Works Great! Recently we did a server migration and transfered the
database to another server. Setup all the groups and security without
a hitch. My users change the Connection to point to the new server and
>
all of a sudden the TransferSpreadsheet function that I'm using in two
seperate procedures starts to error saying that it can't see the table.
>
So I look...and there it is. The function doesn't see it though.
>
>
I try it on my machine and it works fine, but I have Local Admin rights
>
on the server though. So we start looking around. What we found is
that only those with Local Admin Rights and Server Administration
rights seem to be able to execute the procedure so that the
TransferSpreadsheet works correctly.
>
>
Initially I thought that it maybe the way the Server is configured, so
we moved it to another location and tried it again with no luck. Tried
>
putting it back on the original server and again, it works great!
We've used SQL Compair to make sure that something didn't get changed
in the process, and everything looks ok. I will admit that there may
have been something in the way that the first server was configured,
but it doesn't explaine why the function isn't working correctly now.
>
>
All the machines that I tried it on are using the following:
>
>
Desktops:
XP Professional w/SP 1 or 2
ACCESS XP
MDAC 2.8
>
>
Servers:
Windows 2003 Server w/SP1
SQL Server 2000 w/SP4
or
SQL Server 2005 w/SP1 - We've tried both.
>
>
If anyone has any Idea's, I'm open.
>
>
Thank for your time.

|||Hi, Dave

If you specify dbo.TableName, then Access will dumbly look for the
table username.[dbo.TableName]. Unfortunately, it's a bug in Access,
and I agree with the workaround that mcnewsxp wrote (however, running
sp_changeobjectowner requires at least db_ddladmin and db_securityadmin
priviledges in that database).

Another workaround is to have two tables, one for each user who will be
doing the export. For example, if you want to export the data from
TableName, create a dbo.Temp table and a username.Temp table and copy
the data from TableName in both. Then execute TransferSpreadsheet and
it will get the data from one of the Temp tables, depending on the
current user. I know, it's an ugly workaround, but it works...

Razvan

Dave wrote:

Quote:

Originally Posted by

Razvan...Thanks for the reply. I must have left that part out. Sorry.
I did try including dbo.TableName. That also doesn't work. Onething
that I've been talking over with coworkers is Office Versions. The
Test User account that I used, I also used on an Office 2k3 machine.
Everyone else is either using XP or 2K. I know that that shouldn't be
an issue, but right now that's the only thing that's different.
>
I have to try the Test User account on an XP or 2K machine.

|||Sorry I didn't respond to this sooner. We had to get a resolution
quick, so we just used SQL Reporting Services to push the export.

Thanks for everybody's help.

Razvan Socol wrote:

Quote:

Originally Posted by

Hi, Dave
>
If you specify dbo.TableName, then Access will dumbly look for the
table username.[dbo.TableName]. Unfortunately, it's a bug in Access,
and I agree with the workaround that mcnewsxp wrote (however, running
sp_changeobjectowner requires at least db_ddladmin and db_securityadmin
priviledges in that database).
>
Another workaround is to have two tables, one for each user who will be
doing the export. For example, if you want to export the data from
TableName, create a dbo.Temp table and a username.Temp table and copy
the data from TableName in both. Then execute TransferSpreadsheet and
it will get the data from one of the Temp tables, depending on the
current user. I know, it's an ugly workaround, but it works...
>
Razvan
>
Dave wrote:

Quote:

Originally Posted by

Razvan...Thanks for the reply. I must have left that part out. Sorry.
I did try including dbo.TableName. That also doesn't work. Onething
that I've been talking over with coworkers is Office Versions. The
Test User account that I used, I also used on an Office 2k3 machine.
Everyone else is either using XP or 2K. I know that that shouldn't be
an issue, but right now that's the only thing that's different.

I have to try the Test User account on an XP or 2K machine.

Access ADP support SQLExp205

Is there anyone who have an idea when Access ADP (2003) would support SQLExp
2005? Is there any download to make them work together?
Pls help, many thanks.
> Is there anyone who have an idea when Access ADP (2003) would support
> SQLExp 2005? Is there any download to make them work together?
Probably never and no, I do think we'll see a patch to enable it. More here:
http://sqljunkies.com/weblog/ktegels...8/03/3735.aspx
Thank you,
Kent Tegels
DevelopMentor
http://staff.develop.com/ktegels/
sql

Access ADP integration?

I'm sorry but Management Studio is slow, cumbersome and difficult to
quickly make changes while designing a new system. It is directly and
very visibly impacting my teams production. The same can be said for
developing databases though the Visual Studio IDE.
We are at our highest production when using Access ADP projects to
modify the database. It's intuitive, familiar and very responsive. Do
we have to wait until Office 12 before we have Access ADP / SQL 2005
integration?
Please PLEASE don't say this is not going to happen. We are highly
dependent on this and have alot of infrasture in place based on this
setup.
CI would like to expand on my dislike of Management Studio. There is no
copy / paste for tables or views. There is in Access. There is no
Search / Replace in the SQL window. You have to copy all to a text
editor to search and replace.
But I do really like the View Dependancies option though.
C|||Hi
Well, do you have SQL Server 2005 installled as a named instance? I you do
, so a named instance is consumed memory which amy hurt a performance. Also
check out whether you have AutoClose of the database option checked.
In order to make 'copy /paste' as you like in Access you will have to learn
some T-SQL commands as
SELECT * INTO NewTable FROM OldTable
In addition you have a great option in my opinon as Script Table As to make
changes and DML operations

> Search / Replace in the SQL window. You have to copy all to a text
> editor to search and replace.
Have you tried CTRL-F option in the Query Builder?
"The Cornjerker" <addoty@.gmail.com> wrote in message
news:1140311969.961191.275270@.g47g2000cwa.googlegroups.com...
>I would like to expand on my dislike of Management Studio. There is no
> copy / paste for tables or views. There is in Access. There is no
> Search / Replace in the SQL window. You have to copy all to a text
> editor to search and replace.
> But I do really like the View Dependancies option though.
> C
>|||Uri,
Thanks for helping. I'm trying hard to work with Management Studio. I
know I can do anything with SQL commands, but I think the point of
having a tool like Management Studio is to make things visual and
easier. It just doesn't seem very intuitive for rapid development.
CTRL-F is grayed out for me. I can't seem to find the AutoClose option
plus I'm not for sure what it does.
I guess my frustration comes from the fact that I'm constantly being
forced to change my development process. I'm spending more and more my
time and my development team's time learning new processes to do
basically the same thing. VB6 to VB.NET, ASP to ASP.NET, FrontPage to
Visual Studio.NET, now Access ADP to Management Studio. The products
we produce are basically the same, they just take longer to develop and
seem more difficult to maintain. I think there is something to be said
about incrementally improving technologies instead of these huge
revolutionary leaps and then abandoning previous technologies.
Sorry for the rant,
C

Access ADP - SQL server diagram conflicts!

I've run into an annoyance, if I create a new Access project from an
existing SQL database and open up diagrams created earlier with th
enterprise manager Access XP crashes. Creating new diagrams through Access
seems to work just fine. Anyone else run into this? Thanks all.
JonSounds like an Access bug. I'd ask on those newsgroups. It may be
fixed in newer versions of Access.
--Mary
On Thu, 24 Jun 2004 08:25:04 -0400, "Jon" <jonremovemewest@.msn.com>
wrote:

>I've run into an annoyance, if I create a new Access project from an
>existing SQL database and open up diagrams created earlier with th
>enterprise manager Access XP crashes. Creating new diagrams through Access
>seems to work just fine. Anyone else run into this? Thanks all.
>Jon
>

Access ADP - SQL server diagram conflicts!

I've run into an annoyance, if I create a new Access project from an
existing SQL database and open up diagrams created earlier with th
enterprise manager Access XP crashes. Creating new diagrams through Access
seems to work just fine. Anyone else run into this? Thanks all.
JonSounds like an Access bug. I'd ask on those newsgroups. It may be
fixed in newer versions of Access.
--Mary
On Thu, 24 Jun 2004 08:25:04 -0400, "Jon" <jonremovemewest@.msn.com>
wrote:
>I've run into an annoyance, if I create a new Access project from an
>existing SQL database and open up diagrams created earlier with th
>enterprise manager Access XP crashes. Creating new diagrams through Access
>seems to work just fine. Anyone else run into this? Thanks all.
>Jon
>

Access ADP - SQL server diagram conflicts!

I've run into an annoyance, if I create a new Access project from an
existing SQL database and open up diagrams created earlier with th
enterprise manager Access XP crashes. Creating new diagrams through Access
seems to work just fine. Anyone else run into this? Thanks all.
Jon
Sounds like an Access bug. I'd ask on those newsgroups. It may be
fixed in newer versions of Access.
--Mary
On Thu, 24 Jun 2004 08:25:04 -0400, "Jon" <jonremovemewest@.msn.com>
wrote:

>I've run into an annoyance, if I create a new Access project from an
>existing SQL database and open up diagrams created earlier with th
>enterprise manager Access XP crashes. Creating new diagrams through Access
>seems to work just fine. Anyone else run into this? Thanks all.
>Jon
>
sql

Tuesday, March 20, 2012

Access 2k adp

Hi,

I posted this in an access adp newsgroup, but there don't seem to be any
messages there since 9-06.

I am accessing an online SQL Server (2k) database with an Access adp (also
2k). I'm new to doing this.

Does anyone know if I can append records to a SQL Server table thru access?
Will they "mesh"?

Thanks!JA wrote:

Quote:

Originally Posted by

Hi,
>
I posted this in an access adp newsgroup, but there don't seem to be any
messages there since 9-06.
>
I am accessing an online SQL Server (2k) database with an Access adp (also
2k). I'm new to doing this.
>
Does anyone know if I can append records to a SQL Server table thru access?
Will they "mesh"?
>
Thanks!
>
>


Yes, you can. It is just a SQL statament.. I usually use the ADP
functionality if I need a quick/dirty front-end.

Access 2003 and ADP AND sqlserver 2005

Is ADP dying?
Hi
It is being replaced over time by newer technology like "Microsoft Visual
Studio 2005 Tools for the Microsoft Office System"and what will be in Office
12 is not known yet.
The Access engine is really getting to the end of like, especially wit he
functionality supplied by SQL Server 2005 Express Edition.
Regards
Mike Epprecht, Microsoft SQL Server MVP
Zurich, Switzerland
IM: mike@.epprecht.net
MVP Program: http://www.microsoft.com/mvp
Blog: http://www.msmvps.com/epprecht/
"Bruno" <info@.brusoft.be> wrote in message
news:uBGo49D6FHA.632@.TK2MSFTNGP10.phx.gbl...
> Is ADP dying?
>
>
>

Access 2003 and ADP AND sqlserver 2005

Is ADP dying?Hi
It is being replaced over time by newer technology like "Microsoft Visual
Studio 2005 Tools for the Microsoft Office System"and what will be in Office
12 is not known yet.
The Access engine is really getting to the end of like, especially wit he
functionality supplied by SQL Server 2005 Express Edition.
Regards
--
Mike Epprecht, Microsoft SQL Server MVP
Zurich, Switzerland
IM: mike@.epprecht.net
MVP Program: http://www.microsoft.com/mvp
Blog: http://www.msmvps.com/epprecht/
"Bruno" <info@.brusoft.be> wrote in message
news:uBGo49D6FHA.632@.TK2MSFTNGP10.phx.gbl...
> Is ADP dying?
>
>
>

Access 2003 adp/proxy security - A substitute for SYSTEM_USER()

We are moving an Access2000 adp application to Access 2003. Access2000
version uses approle for security but we found Approle does not work the
same in Access2003 so we are switching to a proxy security method.
Problem
We need a way for SQL to know the nt username that initiated the proxy
connection. We need SQL to be able to retrieve that username very, very
quickly (basically without a table lookup) for each user's spids, regardless
of how many connections Access decides to make for the adp.
Details:
a.. All the insert and update triggers depended on SYSTEM_USER to stamp
the user who wrote the data on the row
b.. Many stored procedures and views use a UDF that also depends on
SYSTEM_USER
c.. Since we're reconnecting each user as a proxy user, we need a way for
SQL to determine the nt user of the application.
d.. Note: Modifying the client to pass the user in is simply not practical
due to the huge amount of code change.
Our solution
We are using SET CONTEXT_INFO to stuff the user's name into the context_info
of sysprocesses when the app first logs in. We have a UDF - fnSystemUser
that queries sysprocesses to return what SYSTEM_USER used to. Unfortunately,
for the triggers or any UDFs (which previously only hit SYSTEM_USER), that
meant a nose dive in performance since the UDF is executing on every row
instead of evaluating once as if it were deterministic for the life of that
query. Although SYSTEM_USER is nondeterministic, it appears it was only
evaluated once for the queries instead of the performance we see now on our
UDF returning the system user name from context_info, that indicates
executing on every row.
Since Access adps open multiple connections dynamically our fnSystemUser is
coded to find the Context_info of the spid that was first set through client
code. See the code below:
CREATE FUNCTION dbo.fnSystemUser()
RETURNS nvarchar(50)
AS
BEGIN
DECLARE @.ContextInfo varbinary(128)
DECLARE @.DomainUserName nchar(128)
-- First attempt to get the username stuffed into
-- context_info of this connection
SELECT @.ContextInfo = context_info
FROM master..sysprocesses
WHERE spid = @.@.SPID
-- Convert it to nvarchar
SET @.DomainUserName = CAST(CAST(REPLACE(@.ContextInfo,0x0000,'') AS
varbinary(128)) AS nvarchar(50))
-- If the context info is blank then we're on one of the connections
-- that Access dynamically created but the client code can't access
to stuff
-- something into the context_info. Interrogate all other spids for
this
-- user and this client process (using net_address to guarantee we've
got the
-- right user), to pull username from the context info of another
connection/spid
IF LEN(@.DomainUserName) < 1
BEGIN
DECLARE @.NetAddress nchar(12)
SELECT TOP 1 @.NetAddress = net_address
FROM master..sysprocesses p
WHERE SPID = @.@.SPID
SELECT TOP 1 @.ContextInfo = context_info
FROM master..sysprocesses p
INNER JOIN master..sysdatabases d
on p.dbid = d.dbid
WHERE hostprocess = HOST_ID()
AND d.Name = DB_NAME()
AND NOT CAST(context_info as nchar(50))= SPACE(50)
AND (LEN(@.NetAddress) < 1 OR net_address = @.NetAddress)
ORDER BY Context_info
SET @.DomainUserName =
CAST(CAST(REPLACE(@.ContextInfo,0x0000,'') AS varbinary(128)) AS
nvarchar(50))
END
/* Fail safe, if we couldn't find a non-empty Context_Info to
discover the
logged in user then could be the user is attached with Query
Analyzer or
some other method and we'll just use the user as they are logged
into SQL */
IF LEN(@.DomainUserName) < 1
SET @.DomainUserName = SYSTEM_USER
RETURN
SUBSTRING(@.DomainUserName,CHARINDEX(N'\',@.DomainUs erName)+1,LEN(@.DomainUserN
ame)-(CHARINDEX(N'\',@.DomainUserName)))
END
GO
Solving the performance problem
Here are some workaround we've tried:
a.. Querying sysprocesses seems slow so we instead created a table
SyUserLogin and use HostID() and HostName() to find the right row. We've
seen SQL change HostName (or Workstation ID) to "Pool08" and seen 2 users
have the same HostName. So there is no guarantee that when a user logs in
that HostID() and HostName() will uniquely identify each user. but the odds
are in our favor.
Basically here's what runs (stripped of the uniqueness checks) when the
user first logs in to SQL:
INSERT INTO [dbo].[SyUserLogin]
([UserName], [HostName], [HostID], [NetAddress])
SELECT @.SystemUserName, -- username that we pass in
Host_Name(),
Host_id(),
@.NetAddress -- from the sysprocesses row for this spid
Here's the new fnSystemUser:
CREATE FUNCTION dbo.fnSystemUser()
RETURNS nvarchar(50)
AS
BEGIN
RETURN
(SELECT UpdateUserName
FROM SyUserLogin
WHERE HostName = Host_NAME()
AND HostID = HOST_ID()
)
END
a.. We tried to change the connection string to use either "Application
Name" or "Workstation ID" as a cubby hole to stuff the nt user name. We can
get this to work in a VB Script:
dim objConnection
dim strAccessConnect
strAccessConnect = "Provider=SQLOLEDB.1" & _
";Net=dbnmpntw;Data Source=ASQLServer" & _
";Initial Catalog=MyDatabase" & _
";Persist Security Info=False;Application
Name=MyTestApp;Workstation ID=NTUserName;"
Set objConnection = createobject("ADODB.Connection")
objConnection.Open strAccessConnect, "OurProxy", "ProxyPassword"
Msgbox objConnection.ConnectionString
objconnection.close
set objconnection = nothing
But when we try this in Access2003, Access seems to stomp on those value
when it connects. We've played with the Connection dialog settings, but
can't seem to convince Access to leave our connection string values alone.
If we could get this to work then it would be ideal. Querying HostName() or
even Appname() although obscure would be as fast as SYSTEM_USER()
a.. Could we somehow create a function that would wrap context_info and
match the speed of SYSTEM_USER?
Thank you in advance for reading through this and commenting!
Kimberley Yochum kyochum@.wthq.com
i dont want to sound dumb, but you've tried SUSER_SNAME() and all the other
ones, right?
also, if you're scanning against a large list of Text data, you might want
to consider using HASH INDEXES (aka the checksum function) in order to speed
this.
"Kimberley Yochum" <kyochum@.bigzoo.net> wrote in message
news:%23BOvPMX0EHA.632@.TK2MSFTNGP10.phx.gbl...
> We are moving an Access2000 adp application to Access 2003. Access2000
> version uses approle for security but we found Approle does not work the
> same in Access2003 so we are switching to a proxy security method.
> Problem
> We need a way for SQL to know the nt username that initiated the proxy
> connection. We need SQL to be able to retrieve that username very, very
> quickly (basically without a table lookup) for each user's spids,
regardless
> of how many connections Access decides to make for the adp.
> Details:
> a.. All the insert and update triggers depended on SYSTEM_USER to stamp
> the user who wrote the data on the row
> b.. Many stored procedures and views use a UDF that also depends on
> SYSTEM_USER
> c.. Since we're reconnecting each user as a proxy user, we need a way
for
> SQL to determine the nt user of the application.
> d.. Note: Modifying the client to pass the user in is simply not
practical
> due to the huge amount of code change.
> Our solution
> We are using SET CONTEXT_INFO to stuff the user's name into the
context_info
> of sysprocesses when the app first logs in. We have a UDF - fnSystemUser
> that queries sysprocesses to return what SYSTEM_USER used to.
Unfortunately,
> for the triggers or any UDFs (which previously only hit SYSTEM_USER), that
> meant a nose dive in performance since the UDF is executing on every row
> instead of evaluating once as if it were deterministic for the life of
that
> query. Although SYSTEM_USER is nondeterministic, it appears it was only
> evaluated once for the queries instead of the performance we see now on
our
> UDF returning the system user name from context_info, that indicates
> executing on every row.
> Since Access adps open multiple connections dynamically our fnSystemUser
is
> coded to find the Context_info of the spid that was first set through
client
> code. See the code below:
>
> CREATE FUNCTION dbo.fnSystemUser()
> RETURNS nvarchar(50)
> AS
> BEGIN
> DECLARE @.ContextInfo varbinary(128)
> DECLARE @.DomainUserName nchar(128)
> -- First attempt to get the username stuffed into
> -- context_info of this connection
> SELECT @.ContextInfo = context_info
> FROM master..sysprocesses
> WHERE spid = @.@.SPID
> -- Convert it to nvarchar
> SET @.DomainUserName = CAST(CAST(REPLACE(@.ContextInfo,0x0000,'') AS
> varbinary(128)) AS nvarchar(50))
> -- If the context info is blank then we're on one of the
connections
> -- that Access dynamically created but the client code can't access
> to stuff
> -- something into the context_info. Interrogate all other spids
for
> this
> -- user and this client process (using net_address to guarantee
we've
> got the
> -- right user), to pull username from the context info of another
> connection/spid
> IF LEN(@.DomainUserName) < 1
> BEGIN
> DECLARE @.NetAddress nchar(12)
> SELECT TOP 1 @.NetAddress = net_address
> FROM master..sysprocesses p
> WHERE SPID = @.@.SPID
> SELECT TOP 1 @.ContextInfo = context_info
> FROM master..sysprocesses p
> INNER JOIN master..sysdatabases d
> on p.dbid = d.dbid
> WHERE hostprocess = HOST_ID()
> AND d.Name = DB_NAME()
> AND NOT CAST(context_info as nchar(50))= SPACE(50)
> AND (LEN(@.NetAddress) < 1 OR net_address = @.NetAddress)
> ORDER BY Context_info
> SET @.DomainUserName =
> CAST(CAST(REPLACE(@.ContextInfo,0x0000,'') AS varbinary(128)) AS
> nvarchar(50))
> END
> /* Fail safe, if we couldn't find a non-empty Context_Info to
> discover the
> logged in user then could be the user is attached with Query
> Analyzer or
> some other method and we'll just use the user as they are logged
> into SQL */
> IF LEN(@.DomainUserName) < 1
> SET @.DomainUserName = SYSTEM_USER
> RETURN
>
SUBSTRING(@.DomainUserName,CHARINDEX(N'\',@.DomainUs erName)+1,LEN(@.DomainUserN
> ame)-(CHARINDEX(N'\',@.DomainUserName)))
> END
> GO
> Solving the performance problem
> Here are some workaround we've tried:
> a.. Querying sysprocesses seems slow so we instead created a table
> SyUserLogin and use HostID() and HostName() to find the right row. We've
> seen SQL change HostName (or Workstation ID) to "Pool08" and seen 2 users
> have the same HostName. So there is no guarantee that when a user logs in
> that HostID() and HostName() will uniquely identify each user. but the
odds
> are in our favor.
> Basically here's what runs (stripped of the uniqueness checks) when the
> user first logs in to SQL:
> INSERT INTO [dbo].[SyUserLogin]
> ([UserName], [HostName], [HostID], [NetAddress])
> SELECT @.SystemUserName, -- username that we pass in
> Host_Name(),
> Host_id(),
> @.NetAddress -- from the sysprocesses row for this spid
> Here's the new fnSystemUser:
> CREATE FUNCTION dbo.fnSystemUser()
> RETURNS nvarchar(50)
> AS
> BEGIN
> RETURN
> (SELECT UpdateUserName
> FROM SyUserLogin
> WHERE HostName = Host_NAME()
> AND HostID = HOST_ID()
> )
> END
>
> a.. We tried to change the connection string to use either "Application
> Name" or "Workstation ID" as a cubby hole to stuff the nt user name. We
can
> get this to work in a VB Script:
> dim objConnection
> dim strAccessConnect
> strAccessConnect = "Provider=SQLOLEDB.1" & _
> ";Net=dbnmpntw;Data Source=ASQLServer" & _
> ";Initial Catalog=MyDatabase" & _
> ";Persist Security Info=False;Application
> Name=MyTestApp;Workstation ID=NTUserName;"
> Set objConnection = createobject("ADODB.Connection")
> objConnection.Open strAccessConnect, "OurProxy", "ProxyPassword"
> Msgbox objConnection.ConnectionString
> objconnection.close
> set objconnection = nothing
>
> But when we try this in Access2003, Access seems to stomp on those value
> when it connects. We've played with the Connection dialog settings, but
> can't seem to convince Access to leave our connection string values alone.
> If we could get this to work then it would be ideal. Querying HostName()
or
> even Appname() although obscure would be as fast as SYSTEM_USER()
> a.. Could we somehow create a function that would wrap context_info and
> match the speed of SYSTEM_USER?
> Thank you in advance for reading through this and commenting!
> Kimberley Yochum kyochum@.wthq.com
>
>
|||Thank you Aaron, but all the user functions (System_user, current_user,
session_user, user, user_name, suser_sname, etc.) return the Proxy user name
once a SQL user login has been performed.
Still hoping for some understanding about what Access is doing to my
connection string values or suggestions on what we can do in SQL...
Thank you in advance.
"aaron kempf" <aarkem@.safeco.com> wrote in message
news:OF9GDhZ0EHA.2228@.TK2MSFTNGP15.phx.gbl...
> i dont want to sound dumb, but you've tried SUSER_SNAME() and all the
other
> ones, right?
> also, if you're scanning against a large list of Text data, you might want
> to consider using HASH INDEXES (aka the checksum function) in order to
speed[vbcol=seagreen]
> this.
>
>
> "Kimberley Yochum" <kyochum@.bigzoo.net> wrote in message
> news:%23BOvPMX0EHA.632@.TK2MSFTNGP10.phx.gbl...
> regardless
stamp[vbcol=seagreen]
> for
> practical
> context_info
> Unfortunately,
that[vbcol=seagreen]
> that
> our
> is
> client
AS[vbcol=seagreen]
> connections
access[vbcol=seagreen]
> for
> we've
logged
>
SUBSTRING(@.DomainUserName,CHARINDEX(N'\',@.DomainUs erName)+1,LEN(@.DomainUserN[vbcol=seagreen]
users[vbcol=seagreen]
in[vbcol=seagreen]
> odds
the[vbcol=seagreen]
"Application[vbcol=seagreen]
> can
alone.[vbcol=seagreen]
> or
and
>
|||can you use the application name value instead?
"Kimberley Yochum" <kyochum@.wthq.com> wrote in message
news:%23rCee%23Z0EHA.1404@.TK2MSFTNGP11.phx.gbl...
> Thank you Aaron, but all the user functions (System_user, current_user,
> session_user, user, user_name, suser_sname, etc.) return the Proxy user
name[vbcol=seagreen]
> once a SQL user login has been performed.
> Still hoping for some understanding about what Access is doing to my
> connection string values or suggestions on what we can do in SQL...
> Thank you in advance.
> "aaron kempf" <aarkem@.safeco.com> wrote in message
> news:OF9GDhZ0EHA.2228@.TK2MSFTNGP15.phx.gbl...
> other
want[vbcol=seagreen]
> speed
the[vbcol=seagreen]
very[vbcol=seagreen]
> stamp
way[vbcol=seagreen]
fnSystemUser[vbcol=seagreen]
> that
row[vbcol=seagreen]
only[vbcol=seagreen]
on[vbcol=seagreen]
fnSystemUser[vbcol=seagreen]
> AS
> access
spids[vbcol=seagreen]
another[vbcol=seagreen]
@.NetAddress)
> logged
>
SUBSTRING(@.DomainUserName,CHARINDEX(N'\',@.DomainUs erName)+1,LEN(@.DomainUserN[vbcol=seagreen]
We've[vbcol=seagreen]
> users
> in
> the
> "Application
We[vbcol=seagreen]
_[vbcol=seagreen]
value[vbcol=seagreen]
but[vbcol=seagreen]
> alone.
HostName()
> and
>
|||Yes I would love to but all my attempts to set an App name in the connection
string are being overwritten by Access.
Here's the connection string I tried. When I tried this in a VB script, it
worked fine and sysprocess showed the appname "MyTestApp" and the hostname
"NTUserName". But when I programmatically set the Access
CurrentProject.Connection by opening with the same connection string, those
value get tossed.
strAccessConnect = "Provider=SQLOLEDB.1" & _
";Net=dbnmpntw;Data Source=ASQLServer"
& _
";Initial Catalog=MyDatabase" & _
";Persist Security
Info=False;Application Name=MyTestApp;Workstation ID=NTUserName;"
Any suggestions? Have you had any success in setting this before? I'd love
to hear about it!!
"david epsom dot com dot au" <david@.epsomdotcomdotau> wrote in message
news:%23sSxhz30EHA.1740@.TK2MSFTNGP15.phx.gbl...[vbcol=seagreen]
> can you use the application name value instead?
> "Kimberley Yochum" <kyochum@.wthq.com> wrote in message
> news:%23rCee%23Z0EHA.1404@.TK2MSFTNGP11.phx.gbl...
> name
> want
Access2000[vbcol=seagreen]
> the
proxy[vbcol=seagreen]
> very
on[vbcol=seagreen]
> way
> fnSystemUser
SYSTEM_USER),[vbcol=seagreen]
> row
of[vbcol=seagreen]
> only
> on
> fnSystemUser
through[vbcol=seagreen]
CAST(CAST(REPLACE(@.ContextInfo,0x0000,'')[vbcol=seagreen]
> spids
guarantee[vbcol=seagreen]
> another
> @.NetAddress)
Query
>
SUBSTRING(@.DomainUserName,CHARINDEX(N'\',@.DomainUs erName)+1,LEN(@.DomainUserN[vbcol=seagreen]
> We've
logs[vbcol=seagreen]
the[vbcol=seagreen]
when[vbcol=seagreen]
> We
&[vbcol=seagreen]
> _
Info=False;Application[vbcol=seagreen]
> value
> but
> HostName()
context_info
>
|||> string are being overwritten by Access.
rats. :~(
I'm an Access person, and I don't know anything else you could
try on the Access side. I guess you will be looking for a way
to cache the value, so that fnSystemUser doesn't need to do
SELECT query on every call, but I don't know what the options
are in SQL Server.
(david)
"Kimberley Yochum" <kyochum@.wthq.com> wrote in message
news:OhSjrRA1EHA.3448@.TK2MSFTNGP09.phx.gbl...
> Yes I would love to but all my attempts to set an App name in the
connection
> string are being overwritten by Access.
> Here's the connection string I tried. When I tried this in a VB script,
it
> worked fine and sysprocess showed the appname "MyTestApp" and the hostname
> "NTUserName". But when I programmatically set the Access
> CurrentProject.Connection by opening with the same connection string,
those
> value get tossed.
> strAccessConnect = "Provider=SQLOLEDB.1" & _
> ";Net=dbnmpntw;Data
Source=ASQLServer"
> & _
> ";Initial Catalog=MyDatabase" & _
> ";Persist Security
> Info=False;Application Name=MyTestApp;Workstation ID=NTUserName;"
>
> Any suggestions? Have you had any success in setting this before? I'd
love[vbcol=seagreen]
> to hear about it!!
> "david epsom dot com dot au" <david@.epsomdotcomdotau> wrote in message
> news:%23sSxhz30EHA.1740@.TK2MSFTNGP15.phx.gbl...
current_user,[vbcol=seagreen]
user[vbcol=seagreen]
the[vbcol=seagreen]
might[vbcol=seagreen]
to[vbcol=seagreen]
> Access2000
work[vbcol=seagreen]
> proxy
to[vbcol=seagreen]
> on
a[vbcol=seagreen]
> SYSTEM_USER),
every[vbcol=seagreen]
life[vbcol=seagreen]
> of
now[vbcol=seagreen]
indicates[vbcol=seagreen]
> through
> CAST(CAST(REPLACE(@.ContextInfo,0x0000,'')
can't[vbcol=seagreen]
> guarantee
SPACE(50)[vbcol=seagreen]
to[vbcol=seagreen]
> Query
are
>
SUBSTRING(@.DomainUserName,CHARINDEX(N'\',@.DomainUs erName)+1,LEN(@.DomainUserN[vbcol=seagreen]
table[vbcol=seagreen]
2[vbcol=seagreen]
> logs
> the
> when
name.[vbcol=seagreen]
Source=ASQLServer"[vbcol=seagreen]
> &
> Info=False;Application
settings,[vbcol=seagreen]
values
> context_info
>
|||try with current_user() or user_name()
"david epsom dot com dot au" <david@.epsomdotcomdotau> wrote in message
news:OHiFPga1EHA.2568@.TK2MSFTNGP11.phx.gbl...[vbcol=seagreen]
> rats. :~(
> I'm an Access person, and I don't know anything else you could
> try on the Access side. I guess you will be looking for a way
> to cache the value, so that fnSystemUser doesn't need to do
> SELECT query on every call, but I don't know what the options
> are in SQL Server.
> (david)
>
> "Kimberley Yochum" <kyochum@.wthq.com> wrote in message
> news:OhSjrRA1EHA.3448@.TK2MSFTNGP09.phx.gbl...
> connection
> it
hostname[vbcol=seagreen]
> those
> Source=ASQLServer"
> love
> current_user,
> user
> the
> might
order[vbcol=seagreen]
> to
> work
method.[vbcol=seagreen]
very,[vbcol=seagreen]
spids,[vbcol=seagreen]
> to
depends[vbcol=seagreen]
need[vbcol=seagreen]
> a
not[vbcol=seagreen]
> every
> life
was[vbcol=seagreen]
> now
> indicates
> can't
other[vbcol=seagreen]
> SPACE(50)
Context_Info
> to
> are
>
SUBSTRING(@.DomainUserName,CHARINDEX(N'\',@.DomainUs erName)+1,LEN(@.DomainUserN[vbcol=seagreen]
> table
row.[vbcol=seagreen]
seen[vbcol=seagreen]
> 2
user[vbcol=seagreen]
but[vbcol=seagreen]
spid[vbcol=seagreen]
> name.
> Source=ASQLServer"
those[vbcol=seagreen]
> settings,
> values
SYSTEM_USER()
>

Access 2003 adp/proxy security - A substitute for SYSTEM_USER()

We are moving an Access2000 adp application to Access 2003. Access2000
version uses approle for security but we found Approle does not work the
same in Access2003 so we are switching to a proxy security method.
Problem
We need a way for SQL to know the nt username that initiated the proxy
connection. We need SQL to be able to retrieve that username very, very
quickly (basically without a table lookup) for each user's spids, regardless
of how many connections Access decides to make for the adp.
Details:
a.. All the insert and update triggers depended on SYSTEM_USER to stamp
the user who wrote the data on the row
b.. Many stored procedures and views use a UDF that also depends on
SYSTEM_USER
c.. Since we're reconnecting each user as a proxy user, we need a way for
SQL to determine the nt user of the application.
d.. Note: Modifying the client to pass the user in is simply not practical
due to the huge amount of code change.
Our solution
We are using SET CONTEXT_INFO to stuff the user's name into the context_info
of sysprocesses when the app first logs in. We have a UDF - fnSystemUser
that queries sysprocesses to return what SYSTEM_USER used to. Unfortunately,
for the triggers or any UDFs (which previously only hit SYSTEM_USER), that
meant a nose dive in performance since the UDF is executing on every row
instead of evaluating once as if it were deterministic for the life of that
query. Although SYSTEM_USER is nondeterministic, it appears it was only
evaluated once for the queries instead of the performance we see now on our
UDF returning the system user name from context_info, that indicates
executing on every row.
Since Access adps open multiple connections dynamically our fnSystemUser is
coded to find the Context_info of the spid that was first set through client
code. See the code below:
CREATE FUNCTION dbo.fnSystemUser()
RETURNS nvarchar(50)
AS
BEGIN
DECLARE @.ContextInfo varbinary(128)
DECLARE @.DomainUserName nchar(128)
-- First attempt to get the username stuffed into
-- context_info of this connection
SELECT @.ContextInfo = context_info
FROM master..sysprocesses
WHERE spid = @.@.SPID
-- Convert it to nvarchar
SET @.DomainUserName = CAST(CAST(REPLACE(@.ContextInfo,0x0000,''
) AS
varbinary(128)) AS nvarchar(50))
-- If the context info is blank then we're on one of the connections
-- that Access dynamically created but the client code can't access
to stuff
-- something into the context_info. Interrogate all other spids for
this
-- user and this client process (using net_address to guarantee we've
got the
-- right user), to pull username from the context info of another
connection/spid
IF LEN(@.DomainUserName) < 1
BEGIN
DECLARE @.NetAddress nchar(12)
SELECT TOP 1 @.NetAddress = net_address
FROM master..sysprocesses p
WHERE SPID = @.@.SPID
SELECT TOP 1 @.ContextInfo = context_info
FROM master..sysprocesses p
INNER JOIN master..sysdatabases d
on p.dbid = d.dbid
WHERE hostprocess = HOST_ID()
AND d.Name = DB_NAME()
AND NOT CAST(context_info as nchar(50))= SPACE(50)
AND (LEN(@.NetAddress) < 1 OR net_address = @.NetAddress)
ORDER BY Context_info
SET @.DomainUserName =
CAST(CAST(REPLACE(@.ContextInfo,0x0000,''
) AS varbinary(128)) AS
nvarchar(50))
END
/* Fail safe, if we couldn't find a non-empty Context_Info to
discover the
logged in user then could be the user is attached with Query
Analyzer or
some other method and we'll just use the user as they are logged
into SQL */
IF LEN(@.DomainUserName) < 1
SET @.DomainUserName = SYSTEM_USER
RETURN
SUBSTRING(@.DomainUserName,CHARINDEX(N''
,@.DomainUserName)+1,LEN(@.DomainUserN
ame)-(CHARINDEX(N'',@.DomainUserName)))
END
GO
Solving the performance problem
Here are some workaround we've tried:
a.. Querying sysprocesses seems slow so we instead created a table
SyUserLogin and use HostID() and HostName() to find the right row. We've
seen SQL change HostName (or Workstation ID) to "Pool08" and seen 2 users
have the same HostName. So there is no guarantee that when a user logs in
that HostID() and HostName() will uniquely identify each user. but the odds
are in our favor.
Basically here's what runs (stripped of the uniqueness checks) when the
user first logs in to SQL:
INSERT INTO [dbo].[SyUserLogin]
([UserName], [HostName], [HostID], [NetAddress])
SELECT @.SystemUserName, -- username that we pass in
Host_Name(),
Host_id(),
@.NetAddress -- from the sysprocesses row for this spid
Here's the new fnSystemUser:
CREATE FUNCTION dbo.fnSystemUser()
RETURNS nvarchar(50)
AS
BEGIN
RETURN
(SELECT UpdateUserName
FROM SyUserLogin
WHERE HostName = Host_NAME()
AND HostID = HOST_ID()
)
END
a.. We tried to change the connection string to use either "Application
Name" or "Workstation ID" as a cubby hole to stuff the nt user name. We can
get this to work in a VB Script:
dim objConnection
dim strAccessConnect
strAccessConnect = "Provider=SQLOLEDB.1" & _
";Net=dbnmpntw;Data Source=ASQLServer" & _
";Initial Catalog=MyDatabase" & _
";Persist Security Info=False;Application
Name=MyTestApp;Workstation ID=NTUserName;"
Set objConnection = createobject("ADODB.Connection")
objConnection.Open strAccessConnect, "OurProxy", "ProxyPassword"
Msgbox objConnection.ConnectionString
objconnection.close
set objconnection = nothing
But when we try this in Access2003, Access seems to stomp on those value
when it connects. We've played with the Connection dialog settings, but
can't seem to convince Access to leave our connection string values alone.
If we could get this to work then it would be ideal. Querying HostName() or
even Appname() although obscure would be as fast as SYSTEM_USER()
a.. Could we somehow create a function that would wrap context_info and
match the speed of SYSTEM_USER?
Thank you in advance for reading through this and commenting!
Kimberley Yochum kyochum@.wthq.comi dont want to sound dumb, but you've tried SUSER_SNAME() and all the other
ones, right'
also, if you're scanning against a large list of Text data, you might want
to consider using HASH INDEXES (aka the checksum function) in order to speed
this.
"Kimberley Yochum" <kyochum@.bigzoo.net> wrote in message
news:%23BOvPMX0EHA.632@.TK2MSFTNGP10.phx.gbl...
> We are moving an Access2000 adp application to Access 2003. Access2000
> version uses approle for security but we found Approle does not work the
> same in Access2003 so we are switching to a proxy security method.
> Problem
> We need a way for SQL to know the nt username that initiated the proxy
> connection. We need SQL to be able to retrieve that username very, very
> quickly (basically without a table lookup) for each user's spids,
regardless
> of how many connections Access decides to make for the adp.
> Details:
> a.. All the insert and update triggers depended on SYSTEM_USER to stamp
> the user who wrote the data on the row
> b.. Many stored procedures and views use a UDF that also depends on
> SYSTEM_USER
> c.. Since we're reconnecting each user as a proxy user, we need a way
for
> SQL to determine the nt user of the application.
> d.. Note: Modifying the client to pass the user in is simply not
practical
> due to the huge amount of code change.
> Our solution
> We are using SET CONTEXT_INFO to stuff the user's name into the
context_info
> of sysprocesses when the app first logs in. We have a UDF - fnSystemUser
> that queries sysprocesses to return what SYSTEM_USER used to.
Unfortunately,
> for the triggers or any UDFs (which previously only hit SYSTEM_USER), that
> meant a nose dive in performance since the UDF is executing on every row
> instead of evaluating once as if it were deterministic for the life of
that
> query. Although SYSTEM_USER is nondeterministic, it appears it was only
> evaluated once for the queries instead of the performance we see now on
our
> UDF returning the system user name from context_info, that indicates
> executing on every row.
> Since Access adps open multiple connections dynamically our fnSystemUser
is
> coded to find the Context_info of the spid that was first set through
client
> code. See the code below:
>
> CREATE FUNCTION dbo.fnSystemUser()
> RETURNS nvarchar(50)
> AS
> BEGIN
> DECLARE @.ContextInfo varbinary(128)
> DECLARE @.DomainUserName nchar(128)
> -- First attempt to get the username stuffed into
> -- context_info of this connection
> SELECT @.ContextInfo = context_info
> FROM master..sysprocesses
> WHERE spid = @.@.SPID
> -- Convert it to nvarchar
> SET @.DomainUserName = CAST(CAST(REPLACE(@.ContextInfo,0x0000,''
) AS
> varbinary(128)) AS nvarchar(50))
> -- If the context info is blank then we're on one of the
connections
> -- that Access dynamically created but the client code can't access
> to stuff
> -- something into the context_info. Interrogate all other spids
for
> this
> -- user and this client process (using net_address to guarantee
we've
> got the
> -- right user), to pull username from the context info of another
> connection/spid
> IF LEN(@.DomainUserName) < 1
> BEGIN
> DECLARE @.NetAddress nchar(12)
> SELECT TOP 1 @.NetAddress = net_address
> FROM master..sysprocesses p
> WHERE SPID = @.@.SPID
> SELECT TOP 1 @.ContextInfo = context_info
> FROM master..sysprocesses p
> INNER JOIN master..sysdatabases d
> on p.dbid = d.dbid
> WHERE hostprocess = HOST_ID()
> AND d.Name = DB_NAME()
> AND NOT CAST(context_info as nchar(50))= SPACE(50)
> AND (LEN(@.NetAddress) < 1 OR net_address = @.NetAddress)
> ORDER BY Context_info
> SET @.DomainUserName =
> CAST(CAST(REPLACE(@.ContextInfo,0x0000,''
) AS varbinary(128)) AS
> nvarchar(50))
> END
> /* Fail safe, if we couldn't find a non-empty Context_Info to
> discover the
> logged in user then could be the user is attached with Query
> Analyzer or
> some other method and we'll just use the user as they are logged
> into SQL */
> IF LEN(@.DomainUserName) < 1
> SET @.DomainUserName = SYSTEM_USER
> RETURN
>
SUBSTRING(@.DomainUserName,CHARINDEX(N''
,@.DomainUserName)+1,LEN(@.DomainUserN[vbc
ol=seagreen]
> ame)-(CHARINDEX(N'',@.DomainUserName)))
> END
> GO
> Solving the performance problem
> Here are some workaround we've tried:
> a.. Querying sysprocesses seems slow so we instead created a table
> SyUserLogin and use HostID() and HostName() to find the right row. We've
> seen SQL change HostName (or Workstation ID) to "Pool08" and seen 2 users
> have the same HostName. So there is no guarantee that when a user logs in
> that HostID() and HostName() will uniquely identify each user. but the[/vbcol]
odds
> are in our favor.
> Basically here's what runs (stripped of the uniqueness checks) when the
> user first logs in to SQL:
> INSERT INTO [dbo].[SyUserLogin]
> ([UserName], [HostName], [HostID], [NetAddress]
)
> SELECT @.SystemUserName, -- username that we pass in
> Host_Name(),
> Host_id(),
> @.NetAddress -- from the sysprocesses row for this spid
> Here's the new fnSystemUser:
> CREATE FUNCTION dbo.fnSystemUser()
> RETURNS nvarchar(50)
> AS
> BEGIN
> RETURN
> (SELECT UpdateUserName
> FROM SyUserLogin
> WHERE HostName = Host_NAME()
> AND HostID = HOST_ID()
> )
> END
>
> a.. We tried to change the connection string to use either "Application
> Name" or "Workstation ID" as a cubby hole to stuff the nt user name. We
can
> get this to work in a VB Script:
> dim objConnection
> dim strAccessConnect
> strAccessConnect = "Provider=SQLOLEDB.1" & _
> ";Net=dbnmpntw;Data Source=ASQLServer" & _
> ";Initial Catalog=MyDatabase" & _
> ";Persist Security Info=False;Application
> Name=MyTestApp;Workstation ID=NTUserName;"
> Set objConnection = createobject("ADODB.Connection")
> objConnection.Open strAccessConnect, "OurProxy", "ProxyPassword"
> Msgbox objConnection.ConnectionString
> objconnection.close
> set objconnection = nothing
>
> But when we try this in Access2003, Access seems to stomp on those value
> when it connects. We've played with the Connection dialog settings, but
> can't seem to convince Access to leave our connection string values alone.
> If we could get this to work then it would be ideal. Querying HostName()
or
> even Appname() although obscure would be as fast as SYSTEM_USER()
> a.. Could we somehow create a function that would wrap context_info and
> match the speed of SYSTEM_USER?
> Thank you in advance for reading through this and commenting!
> Kimberley Yochum kyochum@.wthq.com
>
>|||Thank you Aaron, but all the user functions (System_user, current_user,
session_user, user, user_name, suser_sname, etc.) return the Proxy user name
once a SQL user login has been performed.
Still hoping for some understanding about what Access is doing to my
connection string values or suggestions on what we can do in SQL...
Thank you in advance.
"aaron kempf" <aarkem@.safeco.com> wrote in message
news:OF9GDhZ0EHA.2228@.TK2MSFTNGP15.phx.gbl...
> i dont want to sound dumb, but you've tried SUSER_SNAME() and all the
other
> ones, right'
> also, if you're scanning against a large list of Text data, you might want
> to consider using HASH INDEXES (aka the checksum function) in order to
speed
> this.
>
>
> "Kimberley Yochum" <kyochum@.bigzoo.net> wrote in message
> news:%23BOvPMX0EHA.632@.TK2MSFTNGP10.phx.gbl...
> regardless
stamp[vbcol=seagreen]
> for
> practical
> context_info
> Unfortunately,
that[vbcol=seagreen]
> that
> our
> is
> client
AS[vbcol=seagreen]
> connections
access[vbcol=seagreen]
> for
> we've
logged[vbcol=seagreen]
>
SUBSTRING(@.DomainUserName,CHARINDEX(N''
,@.DomainUserName)+1,LEN(@.DomainUserN[vbc
ol=seagreen]
users
in[vbcol=seagreen]
> odds
the[vbcol=seagreen]
"Application[vbcol=seagreen]
> can
alone.[vbcol=seagreen]
> or
and[vbcol=seagreen]
>|||can you use the application name value instead?
"Kimberley Yochum" <kyochum@.wthq.com> wrote in message
news:%23rCee%23Z0EHA.1404@.TK2MSFTNGP11.phx.gbl...
> Thank you Aaron, but all the user functions (System_user, current_user,
> session_user, user, user_name, suser_sname, etc.) return the Proxy user
name
> once a SQL user login has been performed.
> Still hoping for some understanding about what Access is doing to my
> connection string values or suggestions on what we can do in SQL...
> Thank you in advance.
> "aaron kempf" <aarkem@.safeco.com> wrote in message
> news:OF9GDhZ0EHA.2228@.TK2MSFTNGP15.phx.gbl...
> other
want[vbcol=seagreen]
> speed
the[vbcol=seagreen]
very[vbcol=seagreen]
> stamp
way[vbcol=seagreen]
fnSystemUser[vbcol=seagreen]
> that
row[vbcol=seagreen]
only[vbcol=seagreen]
on[vbcol=seagreen]
fnSystemUser[vbcol=seagreen]
> AS
> access
spids[vbcol=seagreen]
another[vbcol=seagreen]
@.NetAddress)[vbcol=seagreen]
> logged
>
SUBSTRING(@.DomainUserName,CHARINDEX(N''
,@.DomainUserName)+1,LEN(@.DomainUserN[vbc
ol=seagreen]
We've
> users
> in
> the
> "Application
We[vbcol=seagreen]
_[vbcol=seagreen]
value[vbcol=seagreen]
but[vbcol=seagreen]
> alone.
HostName()[vbcol=seagreen]
> and
>|||Yes I would love to but all my attempts to set an App name in the connection
string are being overwritten by Access.
Here's the connection string I tried. When I tried this in a VB script, it
worked fine and sysprocess showed the appname "MyTestApp" and the hostname
"NTUserName". But when I programmatically set the Access
CurrentProject.Connection by opening with the same connection string, those
value get tossed.
strAccessConnect = "Provider=SQLOLEDB.1" & _
";Net=dbnmpntw;Data Source=ASQLServer"
& _
";Initial Catalog=MyDatabase" & _
";Persist Security
Info=False;Application Name=MyTestApp;Workstation ID=NTUserName;"
Any suggestions? Have you had any success in setting this before? I'd love
to hear about it!!
"david epsom dot com dot au" <david@.epsomdotcomdotau> wrote in message
news:%23sSxhz30EHA.1740@.TK2MSFTNGP15.phx.gbl...
> can you use the application name value instead?
> "Kimberley Yochum" <kyochum@.wthq.com> wrote in message
> news:%23rCee%23Z0EHA.1404@.TK2MSFTNGP11.phx.gbl...
> name
> want
Access2000[vbcol=seagreen]
> the
proxy[vbcol=seagreen]
> very
on[vbcol=seagreen]
> way
> fnSystemUser
SYSTEM_USER),[vbcol=seagreen]
> row
of[vbcol=seagreen]
> only
> on
> fnSystemUser
through[vbcol=seagreen]
CAST(CAST(REPLACE(@.ContextInfo,0x0000,''
)[vbcol=seagreen]
> spids
guarantee[vbcol=seagreen]
> another
> @.NetAddress)
Query[vbcol=seagreen]
>
SUBSTRING(@.DomainUserName,CHARINDEX(N''
,@.DomainUserName)+1,LEN(@.DomainUserN[vbc
ol=seagreen]
> We've
logs
the[vbcol=seagreen]
when[vbcol=seagreen]
> We
&[vbcol=seagreen]
> _
Info=False;Application[vbcol=seagreen]
> value
> but
> HostName()
context_info[vbcol=seagreen]
>|||> string are being overwritten by Access.
rats. :~(
I'm an Access person, and I don't know anything else you could
try on the Access side. I guess you will be looking for a way
to cache the value, so that fnSystemUser doesn't need to do
SELECT query on every call, but I don't know what the options
are in SQL Server.
(david)
"Kimberley Yochum" <kyochum@.wthq.com> wrote in message
news:OhSjrRA1EHA.3448@.TK2MSFTNGP09.phx.gbl...
> Yes I would love to but all my attempts to set an App name in the
connection
> string are being overwritten by Access.
> Here's the connection string I tried. When I tried this in a VB script,
it
> worked fine and sysprocess showed the appname "MyTestApp" and the hostname
> "NTUserName". But when I programmatically set the Access
> CurrentProject.Connection by opening with the same connection string,
those
> value get tossed.
> strAccessConnect = "Provider=SQLOLEDB.1" & _
> ";Net=dbnmpntw;Data
Source=ASQLServer"
> & _
> ";Initial Catalog=MyDatabase" & _
> ";Persist Security
> Info=False;Application Name=MyTestApp;Workstation ID=NTUserName;"
>
> Any suggestions? Have you had any success in setting this before? I'd
love
> to hear about it!!
> "david epsom dot com dot au" <david@.epsomdotcomdotau> wrote in message
> news:%23sSxhz30EHA.1740@.TK2MSFTNGP15.phx.gbl...
current_user,[vbcol=seagreen]
user[vbcol=seagreen]
the[vbcol=seagreen]
might[vbcol=seagreen]
to[vbcol=seagreen]
> Access2000
work[vbcol=seagreen]
> proxy
to[vbcol=seagreen]
> on
a[vbcol=seagreen]
> SYSTEM_USER),
every[vbcol=seagreen]
life[vbcol=seagreen]
> of
now[vbcol=seagreen]
indicates[vbcol=seagreen]
> through
> CAST(CAST(REPLACE(@.ContextInfo,0x0000,''
)
can't[vbcol=seagreen]
> guarantee
SPACE(50)[vbcol=seagreen]
to[vbcol=seagreen]
> Query
are[vbcol=seagreen]
>
SUBSTRING(@.DomainUserName,CHARINDEX(N''
,@.DomainUserName)+1,LEN(@.DomainUserN[vbc
ol=seagreen]
table
2[vbcol=seagreen]
> logs
> the
> when
name.[vbcol=seagreen]
Source=ASQLServer"[vbcol=seagreen]
> &
> Info=False;Application
settings,[vbcol=seagreen]
values[vbcol=seagreen]
> context_info
>|||try with current_user() or user_name()
"david epsom dot com dot au" <david@.epsomdotcomdotau> wrote in message
news:OHiFPga1EHA.2568@.TK2MSFTNGP11.phx.gbl...
> rats. :~(
> I'm an Access person, and I don't know anything else you could
> try on the Access side. I guess you will be looking for a way
> to cache the value, so that fnSystemUser doesn't need to do
> SELECT query on every call, but I don't know what the options
> are in SQL Server.
> (david)
>
> "Kimberley Yochum" <kyochum@.wthq.com> wrote in message
> news:OhSjrRA1EHA.3448@.TK2MSFTNGP09.phx.gbl...
> connection
> it
hostname[vbcol=seagreen]
> those
> Source=ASQLServer"
> love
> current_user,
> user
> the
> might
order[vbcol=seagreen]
> to
> work
method.[vbcol=seagreen]
very,[vbcol=seagreen]
spids,[vbcol=seagreen]
> to
depends[vbcol=seagreen]
need[vbcol=seagreen]
> a
not[vbcol=seagreen]
> every
> life
was[vbcol=seagreen]
> now
> indicates
> can't
other[vbcol=seagreen]
> SPACE(50)
Context_Info[vbcol=seagreen]
> to
> are
>
SUBSTRING(@.DomainUserName,CHARINDEX(N''
,@.DomainUserName)+1,LEN(@.DomainUserN[vbc
ol=seagreen]
> table
row.
seen[vbcol=seagreen]
> 2
user[vbcol=seagreen]
but[vbcol=seagreen]
spid[vbcol=seagreen]
> name.
> Source=ASQLServer"
those[vbcol=seagreen]
> settings,
> values
SYSTEM_USER()[vbcol=seagreen]
>sql

Monday, March 19, 2012

Access 2000 connection failing to SQL Server2000

Hi guys,
I have an Access .adp project which is connecting to a SQL Server 2000 database. I am using Windows NT authentication.
When I open my access project I get an error message indicating that the stored procedure called from my start up form could not be executed. The problem is that the connection does not appear to have created.
In the main menu I click File and select Connection
The server is correctly selected in the drop down list on the pop up screen.
I click on 'Test Connection' and the I get a message indicating success. Now my project is connected and I can continue through the other forms and reports, executing stored procedures and getting records in my reports.
Any ideas on why the project is not connecting on start up, and why simply testing the connection appears to resolve the problem?
Has it something to do with DNS?First of what is the SP level on SQL server and what is the exact error message?

Access .adp :How to INSERT all but KEY violations

I am trying to append records from one table to another in a db running on
MSDE, knowing fullwell that some of the data in the source will be
duplicates of that in the destination table's pk.
What I would like to happen is to have the stored procedure plunk in all
records that don't violate the constraint
and silently let the duplicate info fall by the wayside. The trouble is SQL
server seems to abort the whole procedure if
even a single record violates the constraint.

In a regular Access mdb, an INSERT statement (append query) would do just
that. Of course it warns you of the violation but a DoCmd.SetWarnings FALSE
takes care of that.

Any ideas as to what I need to do to achieve that same thing?For example:

INSERT INTO TargetTable (key_col, col1, col2, ...)
SELECT S.key_col, S.col1, S.col2, ...
FROM SourceTable AS S
LEFT JOIN TargetTable AS T
ON S.key_col = T.key_col
WHERE T.key_col IS NULL

(where key_col is the primary key).

--
David Portas
SQL Server MVP
--