SQL audit to capture which method called a stored procedure - sql

We have a audit log table which captures the following data:
old value
new value
table name
field name
changed by
changed on
The audit log is implemented via a SQL trigger.
In our application one stored procedure is called by multiple .NET functions. We want to add a new field in the log which will store the name of the .NET function which called the SP, but we're not sure how this can be passed from .NET to a SQL trigger. Does anyone know to a way to do this?

Related

Pass custom data type from one database to another in a stored procedure

I have created a custom data type (user defined table) in my database. I would like to pass this user defined table as a parameter to a stored procedure in a different database.
Is this possible.
thanks

HSQLDB - Get current table name inside a trigger

Is there a way to programmatically get the current table's name inside a trigger's body? I mean the table the trigger is defined for.
I'm looking for a way to do it in SQL but a workaround in Java would be fine too.
There is no SQL function that returns the name of the table during the execution of a TRIGGER. It is easy to define a SQL constant with the table name inside the trigger's SQL code. With triggers defined in the Java language, the fire() method is called by the system. This method has a parameter for the table name which can be accessed in the Java trigger code. http://hsqldb.org/doc/guide/triggers-chapt.html#trc_trigger_action_java

SQL Error with Typed Table

I'm using a user defined table type to pass into my stored proc.
I've had cause to change the table type to add an extra column, and now I get the error:
The parameter "#MyParam" is not the same type as the type it was
created with. Drop and recreate the module using a two-part name for
the type, or use sp_refreshsqlmodule to refresh its parameters
metadata.
when calling the proc from my .net code.
I am adding the param value to my command like so:
var param = _command.Parameters.AddWithValue("#MyParam" , myTypedDataTable)
param.SqlDbType = SqlDbType.Structured;
where myTypedDataTable has been updated to contain the new column.
I have tried dropping and recreating the stored proc that is called, as well as dropping and recreating the User Defined Table.
I have also (thanks to Google) tried to use sys.sp_refreshsqlmodule on my Stored Proc and User Defined Table (It did not work however, on the User Defined Table, giving me the error: "Could not find object '[myUserDefinedTable]' or you do not have permission.", I beleieve this may be due to sys.sp_refreshsqlmodule not being able to work on user defined tables?)
I think I am probably missing something basic here, but can't see what?
I have found the error. There was another stored proc which relied on the user defined table which needed to be dropped and recreated. I'm surprised that this was missed, as when I tried to drop the user defined table first time around, It did not let me as the SP mentioned above referenced it (I had to drop the SP to remove the dependency, then drop the User Defined Table, and then recreate them both), yet it did not complain about a dependency for the newly found SP?
Try to specify the TypeName for the parameter:
param.TypeName = "dbo.YourTableDefinition";

Replication - User defined table type not propagating to subscriber

I created a User defined table type named tvp_Shipment with two columns (id and name) . generated a snapshot and the User defined table type was properly propagated to all the subscribers.
I was using this tvp in a stored procedure and everything worked fine.
Then I wanted to add one more column created_date to this table valued parameter.I dropped the stored procedure (from replication too) and also i dropped and recreated the User defined table type with 3 columns and then recreated the stored procedure and enabled it for publication
When I generate a new snapshot, the changes in user defined table type are not propagated to the subscriber. The newly added column was not added to the subscription.
the Error messages:
The schema script 'usp_InsertAirSa95c0e23_218.sch' could not be propagated to the subscriber. (Source: MSSQL_REPL, Error number: MSSQL_REPL-2147201001)
Get help: http://help/MSSQL_REPL-2147201001
Invalid column name 'created_date'. (Source: MSSQLServer, Error number: 207)
Get help: http://help/207
On the publication, is the replicate_ddl option set to true? Also, what's the value for the pre_cmd value for the article in question? If neither of those point you in the right direction, take a look at the file that it says is failing. It should be a human-readable T-SQL file that's located at the distributor in the snapshot folder. If the error isn't obvious, you can try running it at the subscriber and see what it gives you. My guess is that it didn't replicate the column change, but you put an index on it which references that column. But that's just a guess.

What's the best way to audit log DELETEs?

The user id on your connection string is not a variable and is different from the user id (can be GUID for example) of your program. How do you audit log deletes if your connection string's user id is static?
The best place to log insert/update/delete is through triggers. But with static connection string, it's hard to log who delete something. What's the alternative?
With SQL Server, you could use CONTEXT_INFO to pass info to the trigger.
I use this in code (called by web apps) where I have to use triggers (eg multiple write paths on the table). This is where can't put my logic into the stored procedures.
We have a similar situation. Our web application always runs as the same database user, but with different logical users that out application tracks and controls.
We generally pass in the logical user ID as a parameter into each stored procedure. To track the deletes, we generally don't delete the row, just mark the status as deleted, set the LastChgID and LastChgDate fields accordingly. For important tables, where we keep an audit log (a copy of every change state), we use the above method and a trigger copies the row to a audit table, the LastChgID is already set properly and the trigger doesn't need to worry about getting the ID.