Race condition caused by cursors persisted to temp files - is it possible - race-condition

I'm troubleshooting a problem with a Visual Fox Pro application (built with the Visual Fox Express framework) which I suspect is being caused by a race condition. The application is being hosted on a Citrix XenApp server and under certain conditions, data displayed on a certain form appears to be incorrect, and changes to something other than what the user is entering.
The form in question displays a list of records returned from a query on a SQL Server database based on certain information entered by the user.
If this is what is happening I suspect the sequence of events is something like this:
1) User 1 enters data and causes form to dispay grid of data of
results returned from database.
2) User 2 opens same form on different Citrix session and enters data
causing form to display a grid data of results returned from database.
This cursor gets persisted to disk and overwrites, or somehow
conflicts with User 1's cursor for that form.
3) Some FoxPro cursor mechanism on User 1's instance sees changed data
in the cursor (from User 2) and updates the screen with data from the
cursor.
I don't know much about how FoxPro works but from what I understand in some circumstances a cursor will be persisted to a temp file. On our Citrix application server this temp folder may be shared by between 10 and 50 users. I'm looking for information about if a race condition caused by a cursor written to a file in the temp folder is something that is even possible so that I can continue researching down that path or rule it out definitively.
I know there are ways to make it so that the FoxPro temp files are written to a different folder for each user and I am working on making the change to do that but I would like to find out if anyone else has seen a similar problem or thinks that what I suspect is actually possible.

IT does sound strange, but yes, Foxpro creates temp tables of cursors it uses for display and query results, such as local or remote data access. However, when created, they are created as read-only or read-write, but ONLY for the person per connection. When a cursor attempts to be created, it generates a random file name for the results and uses that as the .dbf cursor for presenting to the user.
COULD IT be a racing issue? I doubt that, but not knowing specifics of the quite old Visual FoxExpress framework, don't know what/where you would configure to have it dynamically use a different location of temp files. It should be going to the temp files path of the Windows environment variables. So, if users of the Citrix connection are using the same user / password for multiple sessions, yes, it would go to the same location, but when trying to generate the temp file, it would fail getting an exclusive handle and try again with the next random file name.

I'd say very unlikely that temp files are implicated here. Each cursor you create uses a different temp file; I don't see how two users, even in a Citrix-type situation, would share a single temp file.

Related

Fix database link - Error 3044?

I have an Access database originally developed in Access 2003 or 2007 that I have inherited. This database is split as a Front-End and Back-End, and I have come across a need to programmatically re-link the back-end due to the technical competence of the people that will be handling this database.
Problem is I get an error 3044 (not a valid path) when attempting to re-link two tables, the rest re-link just fine. The error message displays the original, defunct back-end file in a directory that does not exist. I was able to gleam the cause of the issue from this thread:
"After looking through the issue, it appears the reason you are seeing a problem with these 8 specific tables is because they each have at least one memo field within them that has version history turned on (append only property set to yes). When this property is set to “yes”, it stores additional information about these linked tables within one of the system tables and for whatever reason after the table is initially linked it seems to retain this original link information about these tables."
sounds like a MS Access bug, but there you go. i set those to "no", and so far all is just fine!
This appears to match the behavior, and the solution does indeed work in a defunct version. However we would prefer to keep the option "Append Only" for our tables.
I can delete the linked tables from my front-end and add them back in, and it appears to work fine (ie not breaking anything, yet) for my personal test. Now I want to do this programmatically.
How can I programmatically handle error 3044 and delete/re-add the tables?
Look into DoCmd.TransferDatabase acLink for linking a table with VBA msdn.microsoft.com/en-us/library/office/ff196455.aspx

Users to fetch files remotely

I am using ADO to connect to an access database from an excel spreadsheet using code written in vb. The spreadsheet allows someone to retrieve files stored locally on my machine according to what they enter in certain cells and from interrogating the database. This has worked well which presents the frightening prospect of me now feeling encouraged!...
It is my wish to give a copy of my spreadsheet to people but retain the files and database on my own computer or a dedicated server. ( I do not want the users to be able to access anything other than a view onto the data or the files that I allow them to access). I totally appreciate their are a myriad of alternative technologies that I could and might need to achieve this. But I really am quite a simpleton and would like to be able to simply amend my connection string with something that uses an IP address and similarly with the files. Is this even possible? Can someone advise me where to even start looking for a solution if it is not? I've browsed through stuff on VPN's, application servers, ASP's etc. without even knowing if it is relevant and, as I say, I need the dumbsters solution. I'm happy to read - but what......should I look at VB.net?
A VPN would allow a similar setup to what you have now in as much as your would need to modify the connection string and file paths (to network share paths) but has drawbacks:
Users/you would need to configure a VPN client
Your machine would be the host so would need to be always-on with sufficient bandwidth
Users would be logging on to your machine so you would need to manage access rights/security
This is difficult to scale and a pain in to manage, which is something that is also true of attempting to serve Access content over the internet.
A more standard way to do this would be to:
Get an ASP.NET hosting account with SQL Server support (or set this up on your machine)
Migrate the Access data to SQL Server (which unlike Access is specifically designed to support multiple users over a network)
Update your VBA connection string and make any required changes to your SQL
Create an ASP page that reads the files stored on the server and returns their content
Modify the code you have that loads files from disk to instead query this ASP page over HTTP and read its contents
Retaining Access; you could also create a ASP page that executes queries, reads the data and converts it to XML returned to your spreadsheet for processing.

how to display the result of a procedure running from the server side in oracle?

I am trying to automate a daily monitoring activity where there are set of scripts to be executed(all are select statements). I am in the process of creating a procedure which runs these scripts and by means of scheduler, this will be running daily once. My problem is since these activities are taking place in server side(server backbone), How do i save the results? Earlier we will run all the scripts manually and save it in a notepad. Is there any option to do the same in automation? Like saving in our PC or SQL developer? Instead of logging in to server and searching the path where the file is saved? I thought of saving the results in a table but i am looking for a better option.Please suggest...
Generally it is a good idea to save the results in a table as this gives you flexibility when querying the results or exporting them in multiple formats.
There are multiple options to get the data to the client:
Query the table with the results from the client
Generate a HTML from the results table and have make it accessible from a HTTP server.
You can also create a web PL/SQL package and generate the HTML within (http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_web.htm#i1006207)
Export the data from the results table to a file and put it in a shared directory that is accessible by the client.
Email the results from the PL/SQL package.
I thought of saving the results in a table but i am looking for a better option.
What is exactly the issue with the "table" option?
Regarding "saving in our PC or SQL developer": one problem with that is that a PC/app screen is:
a PC is usually less resilient to reboots, crashes, etc.
it's intended for private use. Unless you're working alone - these logs may be of interest to other people;
..
Other options: it can be made to send e-mail; copy the file to a well known place (incl. one which is directly mounted on your PC); write to database table (as already suggested); and more.

End user friendly sql query run inside excel

I have an Oracle 11G database and sql developer 3.0.04. I have a SQL query which collects useful data for users across a system. The query prompts for two values (using the "&" trick) and then returns a number of columns and rows reflecting their choices. For example, entering "2" at the location prompt, will use the sql query to pull revelant data for that particular location only.
I can connect to the database using Excel 2003. (ODBC Connect) I want to store an excel file on the server, that my users can access to run this query - (as sql developer wouldn't be suitable for these users, too complex)
We have Excel 2003 installed. What do I need to do to let users run the sql query from excel, which will show them the result also in excel?
Thanks!
For what it's worth...
I'd recommend just turning this query into a report in SQL Developer. There's nothing complex about that for your end-users -- they just click on the report they want to run, and it runs (output looks like a table, and they can export it if/as they choose from there). Distributing the report simply requires that you store on a share drive or email it to them (then they import it) -- it's a lot easier than it sounds, and also very convenient for distributing updates / additional reports. With reports, your users won't have to see the SQL, for example (unless they really want to), and the prompts will appear to them as little dialog boxes with plain-english messages (whatever you want them to say).
Anyway, you might find this easier to support / modify / maintain, and I think your users should be happy enough with it (unless they're really grumpy types... :-)

Building an auditing system; MS Access frontend on SQL Server backend

So basically I'm building an app for my company and it NEEDS to be built using MS Access and it needs to be built on SQL Server.
I've drawn up most of the plans but am having a hard time figuring out a way to handle the auditing system.
Since it is being used internally only and you won't even be able to touch the db from outside the building we are not using a login system as the program will only be used once a user has already logged in to our internal network via Active Directory. Knowing this, we're using a system to detect automatically the name of the Active Directory user and with their permissions in one of the DB tables, deciding what they can or cannot do.
So the actual audit table will have 3 columns (this design may change but for this question it doesn't matter); who (Active Directory User), when (time of addition/deletion/edit), what (what was changed)
My question is how should I be handling this. Ideally I know I should be using a trigger so that it is impossible for the database to be updated without an audit being logged, however I don't know how I could grab the Active Directory User that way. An alternate would be to code it directly into the Access source so that whenever something changes I run an INSERT statement. Obviously that is flawed because if something happens to Access or the database is touched by something else then it will not log the audit.
Any advice, examples or articles that may help me would be greatly appreciated!
Does this work for you?
select user_name(),suser_sname()
Doh! I forgot to escape my code.
Ok, it's working here. I'm seeing my windows credentials when I update my tables. So, I bet we missed a step. Let me put together a 1,2,3 sequence of what I did and maybe we can track down where this is breaking for you.
Create a new MSAccess database (empty)
Click on the tables section
Select external data
Pick ODBC database
Pick Link to the datasource by creating a linked table
Select Machine datasource
Pick New...
System Datasource
Pick SQL Server from the list and click Next, Finish.
Give the new datasource a name and description, and select (local) for the server. Click Next.
Pick "With Windows NT authentication using the network login ID". Click Next.
Check Change the default database to, and pick the DB. Click Next. Click Finish.
Test the datasource.
Pick the table that the Trigger is associated with and click OK.
Open the table in Access and modify one of the entries (the trigger doesn't fire on Insert, just Update)
Select * from your audit table
If you specify SSPI in your connection string to Sql, I think your Windows credentials are provided.
I tried playing with Access a bit to see if I could find a way for you. I think you can specify a new datasource to your SQL table, and select Windows NT Authentication as your connection type.
Sure :)
There should be a section in Access called "External Data" (I'm running a new version of Access, so the menu choice might be different).
Form this there should be an option to specify an ODBC connection.
I get an option to Link to the datasource by creating a linked table.
I then created a Machine datasource. I selected SqlServer from the drop down list. Then when I click Next, I'm prompted for how I want to authenticate.
CREATE TRIGGER testtrigger1
ON testdatatable
AFTER update
AS
BEGIN
INSERT INTO testtable (datecol,usercol1,usercol2) VALUES (getdate(),user_name(),suser_sname());
END
GO
We also have a database system that is used exclusively within the organisation and use Window NT logins. This function returns the current users login name:
CREATE FUNCTION dbo.UserName() RETURNS varchar(50)
AS
BEGIN
RETURN (SELECT nt_username FROM master.dbo.sysprocesses WHERE spid = ##SPID)
END
You can use this function in your triggers.
It should be
select user name(),suser sname()
replace spaces with underscores
you need to connect with integrated security aka trusted connection see (http://www.connectionstrings.com/?carrier=sqlserver)
How many users of the app will there be? Is there possibility of using windows integrated authentication for SQL authentication?
Updated: If you can give each user a SQL login (windows integrated) then you can pickup the logged on user using the SYSTEM_USER function.
My solution would be not to let Access modify the data with linked tables.
I would only create the UI in Access and create an ADO connection to the server using windows authenticated in the connection string. Compile you Access application as dbe to protect the VB code.
I would not issue SQL statement, but I would call stored procedures to perform the changes in the database, and create the audit log entry in an atomic transaction.
The UI (Access) does not need to know the inner works on the server. All it needs to do is request and update/insert/delete using the stored procedures you would create for this purpose. The server should handle the work.
Retrieve a record set with ADO using a view with the hint NOLOCK implemented in the server and cache this data in Access for local display. Or retrieve a single record and lock only that row for editing.
Using linked tables your users will be locking each other.
With ADO connections you will not have the trouble to set ODBCs on every single client.
Create a table to set the server status. You application will check it before any action. you can use it to close the server to the application in case that you need to perform changes or maintenance.
Access is a great tool. But it should only handle its local data and not be allowed to mess with the precious server.