Sql Server: logging in stored procedure - sql-server

I have a stored procedure that is called from a c# application.
The transaction is started and commited/rolledback from this c# application.
The stored procedure can do some inserts/updates in various tables, which will all be commited or rolledback by the calling application.
The problem is that the stored procedure also insert records into a logtable, which must survive the rollback.
What is the best way of doing this ?
I think I remember from a company I worked for long ago they had solved this by creating a stored procedure for the logging, and this stored procedure had some exotic statements that made it work outside the transaction, something like that. As I said, long time ago I could remember this wrong.

Some times ago, I've develop a tools that logged stored procedure execution in a databases table. The tools was written as a C# assembly compiled into the Database Server and based on differents SQL procedures and functions linked to its C# entry points.
To allow a rollback without the lost of all events allready logged, the C# assembly SHOULD used a full defined connectionString to connect to its database server (SERVERNAME\INSTANCE server param instead of local).
This is perhaps the solution used by your previous company.
Meanwhile, there are some disadvantages:
thoses connections was qualified as "external" and the "truthfully" databases parameters should be set to true to allow code execution if not signed
this solution is not supported on clouded databases (AWS RDS or Azure)
A new connection is created by C# methods
For this last reason and a customer need, I've rewrite a toolbox based on 100% T-SQL source code.
I've just write a response which can be usefull see: https://stackoverflow.com/a/32988757/1183297

Related

Best practice deploying Stored Procedures to multi DB with same structure?

We have one website currently being used by 3 clients. We have 3 different versions of the same source code which is calling 3 different databases. So,
1) Client A access "http://custA.weblink.com" will access "CustA" Database
2) Client B access "http://custB.weblink.com" will access "CustB" Database
3) Client C access "http://custC.weblink.com" will access "CustC" Database
All databases have the same structure, table design and stored procedures. Only the data is different.
The issue is, when I need to do deployment for stored procedures, I need to repeat the backup and perform deployment 3 times. It's not really hard even when there are lots of stored procedures need to be deployed but doesn't seems like a good practice.
Now I only have 3 clients, what if in the future I have 10? I need to repeat backup and deployment 10 times which is time consuming and it's hard to guarantee that all stored procedures in all databases will always be the same.
In this type of case where I have existing multi applications and databases, what could be the good practice or measurements to take to make the situation better? I don't think my company will allow making huge changes like merging all clients data into one database and re-write application flow to get the right data.
I thought about creating one main database without any data. All the Stored Procedures script will be deployed there. And each of the existing "CustA", "CustB" and "CustC" DB, I will use to EXEC method to call Stored Procedure from main database to process the data in the relevant DB. Like this:
1) Main database
USE [MainDatabase]
ALTER PROCEDURE USP_GetCustomerById
#CustId BIGINT
SELECT * FROM [Customer] WHERE Id = #CustId
2) CustA database (Same flow for CustB and CustC database)
USE [CustA]
ALTER PROCEDURE USP_GetCustomerById
#CustId BIGINT
EXEC MainDatabase.dbo.USP_GetCustomerById #CustId
Will there be any impact if I do so?
Have you ever considered to use visual studio to create an SQL Server Database Project? Here you can import for instance the first server ClientA settings for a single Database. It will import (schemas,objects,views,indexes and so on) And then you can setup different deployment servers. You can also compare Source and destination (A and B) to each other, to see if you have differences. (I
Example on deploying on Database to multiple servers
As you can see in my picture i have the whole structure for one database. In the bottom of the Solution Explorer you can see i have something called PROD and TEST. This is actually two different servers. You could create the 3 servers you need and then you can just press deploy.
Example on Schema compare
Here i have compared a source with my project. Then i can import my changes i made on ClientA and inject them to my project, so i can deploy them to the other servers.

Same app for multiple clients and custom stored procedures in SQL Server

We have the same app source (with some custom "if x client then") and basically the same SQL Server database structure. But, some clients need slightly different stored procedures.
What would be best practice in this scenario for long term maintaining the databases and keeping the correct structure? As of now, for example when I change the procedure in one database and need to do the same in 9/10 others I just ALTER procedure and USE different database. But, I can't keep track of which procedures are different in that special snowflake client.
Any ideas? The plan is of course to get more clients so that's looking for trouble.
I try to push the "one fits all" concept but hey, what can you do...
Maybe have that "if x client then" as case statement in a SQL Server stored procedure and then you can just ALTER mindlessly?

CLR Stored Procedure v regular SQL Stored Procedure

I have been writing a CLR stored procedure that moves data from one database to another. I went with the CLR stored procedure because I like the .NET framework's ability to connect to remote servers better than I like linked servers, or openrowset, but I now find that my class is mostly embedded SQL strings. I was considering just using the CLR stored procedures to retrieve the data onto the local SQL Server, and then using a regular SQL stored procedure for the actual inserts and updates.
I'm not worried about pre-compilation of the procedure or performance, and I do like that the CLR procedure allows me to see all of the logic in one place, read from top to bottom.
Are there any reasons I should consider moving to a TSQL solution instead of CLR?
Thanks.
There are multiple reasons why you would stick to a regular stored procedure. I'll try to give you an overview of the ones that I know of:
Performance.
Memory issues. SQL Server only operates with its own max memory settings. CLR's go out of this bound. This could comprimise other applications (and the OS) running on this server.
Updatebility. You can update a Stored procedure with a simple script. CLR's are more complicated to update
Security. CLR's often require more security settings than regular t-sql.
As a general rule you only want to use CLR for:
interaction with the OS, such as reading from a file or dropping a message in MSMQ
performing complex calculations, especially when you already have the code written in a .NET language to do the calculation.

Security Audit (CRUD) - Microsoft Access

My client has been using Microsoft Access 2010 for quite a while and they received some Security Audit Requirements. They are using a Linked Tables approach connecting to Microsoft SQL Server 2012 Express.
The requirements states that all actions against the data must be logged. (INSERT, UPDATE, DELETE AND SELECT statements)
For the INSERT, UPDATE, DELETE statements I could create a trigger which would log the changes.
The issue is around the audit of SELECT statements. If the data was read-only, I could have used a Stored Procedure which would have logged the query. But executing a Stored Proc makes a Recordset not updatable.
Does anyone have an idea how to approach this challenge?
I'm open to a lot of strategies... (Connecting Access to SQL through a web service, anything...)
It's important to note that my client does not have $30k to spend on an Enterprise edition of SQL Sever as they are a small-business with less than 10 employees.
SELECT statements are part of the database-level audit action groups in SQL Server. (Search that page for "database-level audit actions".) But that level of auditing requires SQL Server Enterprise edition.
Theoretically, you can limit all access to use only stored procedures regardless of whether the data is read-only. Write the stored procedure to write auditing information to the log first, then do whatever else needs to be done--SELECT, INSERT, etc.
Practically, you might not be able to do that. It depends on the applications that hit your database. Limiting all access to use only stored procedures can break applications that expect other things. (How would a Ruby on Rails application respond if you switched to just stored procedures?)
A bulletproof audit system that makes your database unusable isn't very good; it's simpler and cheaper to just shut down the database server altogether.
You could upgrade to a SQL Server edition that supports SQL Server profiler.
The other option is to get other tools to audit like sql audit for example.
You could turn on JET showplan. This would log all queries used by Access.
http://www.techrepublic.com/article/use-microsoft-jets-showplan-to-write-more-efficient-queries/?siu-container
As I pointed out in comments you really fooling the audit requirements UNLESS each form is opened using a where clause that limits the viewing of data in that form to the ONE record. If you don’t do this, then a form opened to a linked table could have 1000’s of records, and user(s) hitting ctrl-f to find and jump to one record means the SELECT statement tells you ZERO about what the user actually looked at. So while you can turn on show plan, the audit concept would not tell you anything about what the user actually looked at unless application design changes are made to restrict forms to one record. And to be fair, 99% of my applications in fact do open and restrict the main editing form to the one record via a where clause.
So while you can technology wise log all SELECT commands as per above, it not really in the sprit of such a log since such a log would not be of any use to determine what actual records the user looked at.

Compatible DDL (CREATE TABLE) across different SQL databases?

I'm working on a desktop application that must support (currently) MS Access and SQL Server back ends. The application is under constant development and changes are frequently being made to the database, mostly the addition of tables and views to support new features (but also some DROPs and ALTER TABLEs to add new columns).
I have a system that compiles the DDL into the executable, checks the database to see if the executable has any new DDL that has to be executed, and executes it. This works fine for a single database.
My immediate problem is that SQL Server and Access support wildly different names for data types so a CREATE TABLE statement that executes against Access will not execute against SQL Server (or worse, will execute but create a table with different datatypes).
Is there a method that can be used to create DDL (especially CREATE TABLE commands) that can be executed through ADO against both of these databases without having to craft separate DDL for each provider?
Since you are already using ADO, you should look into Microsoft ADOX
This allows you to manipulate structures in a data source using an ADO object model that is independent of the underlying data source type. i.e. without resorting to explicit DDL
Support for ADOX is not guaranteed by any given ADO Provider, and the level of ADOX support may vary even when it is available. But for MS Access and MS SQL Server I think you will find all the capability you require (and quite possibly more!)
This can be done using DBX in Delphi.
The following is links to sample code showing how this can be done.
http://cc.embarcadero.com/item/26210
I had the same problem.
I resolved it applying a C preproccessor to the SQL before executing it.
The preprocessor includes macros in order to handle the different dbs.
Stefano
Did you check
http://db.apache.org/ddlutils/
or
http://publib.boulder.ibm.com/infocenter/wtelecom/v6r1/index.jsp?topic=%2Fcom.ibm.twss.plan.doc%2Fdb_scripts.html

Resources