One of the most important databases that I administer is poorly designed. The program which uses it uses only 1 login which happens to be a System Administrator. Edits and deletes are done in place so change tracking is difficult.
Further, it lacks proper auditing functionality so I cannot tell which user edited or deleted a certain record.
I thought I might resort to using SQL triggers and output the record information along with information about the user who edited/deleted it. I can't use LoginName because the program only uses one login.
Can I export other information using a trigger such as the desktop machine name which sent the delete command?
Is there any other information that I could export that would assist me in this?
You might look at the sys.sysprocesses table (sysprocesses in SQL Server 2000 I think). It contains information that you normally see in the output of the sp_who2 stored procedure. It includes hostname, which is the computer that is connecting to SQL Server. Some of the other columns may be useful too.
Related
I need to collect data from a SQL Server table, format it, and then put it into a different table.
I have access to SQL Server but cannot setup triggers or scheduled jobs.
I can create tables, stored procedures, views and functions.
What can I setup that will automatically collect the data and insert it into a SQL Server table for me?
I would probably create a stored procedure to do this task.
In the stored procedure you can create a CTE or use temp tables (depending on the task) and do all the data manipulation you require and once done, you can use the SELECT INTO statement to move all the data from the temp table into the SQL Server table you need.
https://www.w3schools.com/sql/sql_select_into.asp
You can then schedule this stored procedure to run at a time desired by you
A database is just a storage container. It doesn't "do" things automatically all by itself. Even if you did have the access to create triggers, something would have to happen to the table to cause the trigger to fire, typically a CRUD operation on the parent table. And something external needs to happen to initiate that CRUD operation.
When you start talking about automating a process, you're talking about the function of a scheduler program. SQL Server has one built in, the SQL Agent, and depending on your needs you may find that it's appropriate to enlist help from whoever in your organization does have access to it. I've worked in a couple of organizations, though, that only used the SQL Agent to schedule maintenance jobs, while data manipulation jobs were scheduled through an outside resource. The most common one I've run across is Control-M, but there are other players in that market. I even ran across one homemade scheduler protocol that was just built in C#.NET that worked great.
Based on the limitations you lay out in your question, and the comments you've made in response to others, it sounds to me like you need to do socialize your challenge within your organization to find out what their routine mechanism is for setting up data transfers. It's unlikely that this is the first time it's come up, unless the company was founded in the last week or two. It will probably require that you set up your code, probably a stored procedure or maybe an SSIS package, and then work with someone else, perhaps a DBA or a Site Operations team or some such, to get that process automated to fire when you need it to, whether through an Agent job or maybe a file listener.
Well you have two major options, SP and SSIS.
Both of them can be scheduled to run at a given time with a simple Job from the SQL Server Agent. Keep in mind that if you are doing this on a separate server you might need to add the source server as a Linked Server so you can access it from the script.
I've done this approach in the past and it has worked great. Note, for security reasons, I am not able to access the remote server's task scheduler, so I go through the SQL Server Agent:
Run a SQL Server Agent on a schedule of your choice
Use the SQL Server Agent to call an SSIS Package
The SSIS Package then calls an executable which can pull the data you want from your original table, evaluate it, and then insert a formatted version of it, one record at a time. Alternatively, you can simply create a C# script within the SSIS package via a Script Task.
I hope this helps. Please let me know if you need more details.
I am not sure what the correct forum is for a question like this, so if it would go better on a different one could you move it there please?
I have split my database into a front and back-end database. The front end is using linked tables which are linked to the back-end real tables. If a user changes something in a table on the front-end database, the changes are carried over to the backend database.
Why is this and how can I prevent this from happening? Is there a way to change the settings to make the database read only? Whether it's through VBA or not, I would accept either answer.
That's a feature, not a bug. You're using a linked table, it's linked.
If you want a separate table, make a separate table, and make some ETL (extract/transform/load) process to keep the two tables in sync as needed, accordingly with whatever business rules you need to implement.
If your Access DB is connecting to SQL Server via SQL authentication, you could have the SQL user on the SQL Server side only authorized to SELECT, and denied UPDATE, DELETE and INSERT permissions. Expect errors on the Access side when the linked table is modified then.
I'm a little lost and need some guidance on how to approach this feature I'd like to add.
Many operations I use require retrieving data from a remote server. My goal is to be able to receive an email notification if new data has been added to the remote server.
I thought about creating a stored procedure that uses "openquery" and compare data to a local table with a conditional statement that will send out an email if there are differences. Then scheduling a job that will execute this stored procedure frequently. But this does not feel elegant at all...
If I understood your question correctly, all depends on the permissions.
If I was the owner of the system
Find out which job is adding data to the system. Modify the process (ETL/ SQL job etc.) to send you an email. (best way)
If you have create permissions on the remote system
Create an after insert trigger, see the first example here. Refer to this link as well. (2nd best way)
If you have just permissions to create linked server
Whatever you wrote/ you can bring the data from the server (just the primary keys from the table) and keep on checking that by creating a job for new primary keys if any by copying the data to local.
How to choose between these two: depends on the size of data. Second method mentioned in point 3 will work even without a linked server.
But you will have to run this again and again, I can't think of any other way. Set up a SQL job/ ETL to do this for you.
I use "Lexware Warenwirtschaft Premium 2014" (a well-known merchandise management software in Germany). It uses Sybase as a database. I connect to the database by using a ODBC connection(SQL Anywhere driver). The database has 800+ tables. For example when Lexware creates a new Article, it writes data into different tables.
Is there a way to track into which tables Lexware wrote data?
As an ad-hoc measure you could switch on ODBC tracing, and then review the contents.
http://support.microsoft.com/kb/274551 tells you how to do this from a Windows client, and you can find similar information for Linux/Unix and other clients.
You'd then have to parse the trace file to see which queries were inserted into. The first step would probably be to isolate all the SQLPrepare and SQLExecDirect statements, and check them for INSERT, UPDATE and other relevant Sybase statements.
Note that this is not something you'd want as an ongoing solution, just a way to find out what an ODBC client does if you do not have access to e.g. logging information on the database itself. However, the trace slows down execution and would generate a very large trace file if you left it running for any significant period.
I don't think so. Whatever this program does behind the interface is hidden in its binaries and unreadable for humans, so you can't read the code to see which tables are altered.
You might be able to figure out which table was edited last, depending on the SQL-Server and it's version.
I have a delicate situation wherein some records in my database are inexplicably missing. Each record has a sequential number, and the number sequence skips over entire blocks. My server program also keeps a log file of all the transactions received and posted to the database, and those missing records do appear in the log, but not in the database. The gaps of missing records coincide precisely with the dates and times of the records that show in the log.
The project, still currently under development, consists of a server program (written by me in Visual Basic 2010) running on a development computer in my office. The system retrieves data from our field personnel via their iPhones (running a specialized app also developed by me). The database is located on another server in our server room.
No one but me has access to my development server, which holds the log files, but there is one other person who has full access to the server that hosts the database: our head IT guy, who has complained that he believes he should have been the developer on this project.
It's very difficult for me to believe he would sabotage my data, but so far there is no other explanation that I can see.
Anyway, enough of my whining. What I need to know is, is there a way to determine who has done what to my database?
If you are using identity for your "sequential number", and your insert statement errors out the identity value will still be incremented even though no record has been inserted. Just another possible cause for this issue outside of "tampering".
Look at the transaction log if it hasn't been truncated yet:
How to view transaction logs in SQL Server 2008
How do I view the transaction log in SQL Server 2008?
If you want to catch the changes in real time, I suggest you consider using SqlDependency. This way, when data changes, you will be alerted immediately and can check which user is using the database at the very moment (this could also be done using code).
You can use this code sample.
Coming to think about it, you can establish the same effect using a trigger and writing ti a table active users. Of course, if you are suspecting someone is tempering with data, using SqlDependency might be a better way to go with, as the data will be stored outside of the tampered database.
You can run a trace, for example a distant profiler trace, that will get all SQL queries containing the DELETE keyword. This way, nobody will be aware that queries are traced. You can also query the default trace regularly to get the last DELETE commands: Maintaining SQL Server default trace historical events for analysis and reporting