Persistent SQL Table lock from C# - sql

I'm trying to create a persistent SQL (SQL Server 2005) lock on a table level. I'm not updating/querying the specified table, but I need to prevent a third party application from updating the locked table as a means to prevent transactions from being posted (the table I wish to lock is the key on their transaction that interferes with my processing).
From my experience the table is only locked for the time a specific transaction is taking place. Any ideas?
The 3rd party developer has logged this feature as an enhancement, but since they are in the middle of rolling out a major release I can expect to wait at least 6 months for this. I know that this isn't a great solution, since their software will fall over but it is of a critical enough nature that we're willing to live with the consequences.

Move the table to a different file group, then alter the file group to read-only. The table will be in effect read-only:
ALTER DATABASE dbName
ADD FILEGROUP ReadOnlyFG;
GO
ALTER DATABASE dbName
ADD FILE (
NAME = ...,
FILENAME = '...')
TO FILEGROUP ReadOnlyFG;
GO
ALTER TABLE tableName MOVE TO ReadOnlyFG;
GO
ALTER DATABASE dbName
MODIFY FILEGROUP ReadOnlyFG READONLY;

rename the table and when the 3rd party is ready rename it back to what it should be

Related

How to safely drop / delete a table?

I need to drop a table but I want to be 100% sure the table is unused first. How can I do so with complete certainty?
I've already:
Made sure there are no references to the table in the codebase
Dropped the table in the staging environment over a week ago
Renamed the table in production (I appended _to_delete at the end) over a week ago
Asked other engineers if table is needed
I suppose I can revoke permissions to the table from the application database user as a next step. What I would love is to be able to record table access to know for sure that table is not being referenced, but I wasn't able to find a way to do that over a specific timeframe.
And yes, I'm realize I'm being a bit paranoid (I could always restore the table from backup if it turns out it's needed) but I'm not a DBA so I'd prefer to be extra cautious.
Create a backup of the table and then drop the table, if application breaks then you always have the option to re-create it with the backup table.
Paranoia is a virtue for a database administrator.
Revoking permissions seems like a good way to proceed.
To check if the table is used, observe the seq_scan and idx_scan columns of the pg_stat_user_tables entry for the table. If these values don't change, the table is not accessed. These values are not 100% accurate, since statistics are deliberately sent via a UDP socket, but if the numbers don't change at all, you can be pretty certain that the table is unused.

How do I link the File Table with my existing table in SQL server

I have a requirement of saving employees image in database. I have been asked to use File Tables. After googling on this I got some fine contents as to how to get started with File Tables. And I managed to create them, also inserting data to these tables is as simple as copy/paste to specified folder and the data gets inserted into the table. The problem is how do I relate each employee row set with their respective images
The overall flow will be like the employee will upload his/her image or doc through front end, which will save the image on the server. the problem is how to add reference of employee with its respective image. One option can be having a FileName column in the employee table which refers to the name column in the FileTable, but I need something more efficient such as relating the id's. Any other way of achieving this would be appreciated.
First of it consumed a lot of time to get things right as filetable being a new feature introduced from SQLSERVER 2012 onwards. Secondly this is the approach I took to counter my issue. I will be providing some usefull links to make life easier for other developers. Hope it helps.
File table is almost similar to normal SQL tables, but has some configurations to be made to get it started, as it resides in a separate section of your database, inside tables-->FIleTables. Since the table structure is predefined, you cannot change the table schema. So the approach I took is to refer the stream_id as the reference key to link with the table that I want to use and handle the constrains logic through stored procedure. In my scenario the Employee table will have a stream_id column which will be linked to the File table via stream_id, also to make rows in the File table unique, I inserted the Employee Id as the name of the stored image and not the actual name of the file. With this even if anyone tries to insert the file directly by copy/paste it wouldn't have any relation with the Employee table, also you can provide access right to give desired permission. Check the links for more details. And that's it, with a little bit of tweaks I was able to solve my issue.
Below SQL scripts will be helpful to activate file stream at instance level at one shot.
EXEC sp_configure filestream_access_level, 2
RECONFIGURE
GO
--For new DB
CREATE DATABASE <DATABASE name>
WITH FILESTREAM
(
NON_TRANSACTED_ACCESS = FULL,
DIRECTORY_NAME = N'<DIRECTORY name>'
);
GO
--If you have an existing DB
ALTER DATABASE <DATABASE name>
ADD FILEGROUP <File group name>
CONTAINS FILESTREAM
GO
ALTER DATABASE <DATABASE name>
ADD FILE (NAME='<File group name>', FILENAME='<DIRECTORY name>')
TO FILEGROUP <File group name>
GO
ALTER DATABASE <DATABASE name>
SET FILESTREAM ( NON_TRANSACTED_ACCESS = FULL, DIRECTORY_NAME = N'<File
group name>')
GO
use <DATABASE name>
GO
CREATE TABLE <Filetable NAME> AS FileTable;
GO
Also some links which are very helpful:
https://www.mssqltips.com/sqlservertip/2667/filetable-feature-in-sql-server-2012/
http://sql-articles.com/articles/general/working-with-filetables/
https://michaelfirsov.wordpress.com/working-with-sql-server-file-tables-part-1/
https://michaelfirsov.wordpress.com/working-with-sql-server-file-tables-part-2/
https://msdn.microsoft.com/pl-pl/library/gg492084(v=sql.110).aspx
Thanks.
Wouldn't just having a "joining (many-to-many) table" in between employer and the filetable be just as easy? You wouldn't have to use it as a many-to-many table. Call it EmployeeImages and add a description attribute/property i.e "Hiring photo", "Just got fired photo". with both primary keys from employee and filetable. simples!
You have to insert in your program the code for copying file.
File.Copy(...) Instead of just copying and pasting into file system.
So that, each instance that your File.Copy executes, you can get its respective stream_id, which then you attach on your employees table..

How to recover table after drop it in SQL Server

I drop a table in SQL Server using this code:
DROP TABLE temp
Now, I try to recover this table, but I don't know a solution.
Please, tell me a solution for this problem if you know.
If DROP TABLE was executed inside the Transaction and it has not been committed then you can ROLLBACK. But if it isn't, then you need backup of your database. Recover your table from database. If backup is also not present, then search for 3rd party recovery tools.

How to delete a large record from SQL Server?

In a database for a forum I mistakenly set the body to nvarchar(MAX). Well, someone posted the Encyclopedia Britanica, of course. So now there is a forum topic that won't load because of this one post. I have identified the post and ran a delete query on it but for some reason the query just sits and spins. I have let it go for a couple hours and it just sits there. Eventually it will time out.
I have tried editing the body of the post as well but that also sits and hangs. When I sit and let my query run the entire database hangs so I shut down the site in the mean time to prevent further requests while it does it's thinking. If I cancel my query then the site resumes as normal and all queries for records that don't involve the one in question work fantastically.
Has anyone else had this issue? Is there an easy way to smash this evil record to bits?
Update: Sorry, the version of SQL Server is 2008.
Here is the query I am running to delete the record:
DELETE FROM [u413].[replies] WHERE replyID=13461
I have also tried deleting the topic itself which has a relationship to replies and deletes on topics cascade to the related replies. This hangs as well.
Option 1. Depends on how big the table itself and how big are the rows.
Copy data to a new table:
SELECT *
INTO tempTable
FROM replies WITH (NOLOCK)
WHERE replyID != 13461
Although it will take time, table should not be locked during the copy process
Drop old table
DROP TABLE replies
Before you drop:
- script current indexes and triggers so you are able to recreate them later
- script and drop all the foreign keys to the table
Rename the new table
sp_rename 'tempTable', 'replies'
Recreate all the foreign keys, indexes and triggers.
Option 2. Partitioning.
Add a new bit column, called let's say 'Partition', set to 0 for all rows except the bad one. Set it to 1 for bad one.
Create partitioning function so there would be two partitions 0 and 1.
Create a temp table with the same structure as the original table.
Switch partition 1 from original table to the new temp table.
Drop temp table.
Remove partitioning from the source table and remove new column.
Partitioning topic is not simple. There are some examples in the internet, e.g. Partition switching in SQL Server 2005
Start by checking if your transaction is being blocked by another process. To do this, you can run this command..
SELECT * FROM sys.dm_os_waiting_tasks WHERE session_id = {spid}
Replace {spid} with the correct spid number of the connection running your DELETE command. To get that value, run SELECT ##spid before the DELETE command.
If the column sys.dm_os_waiting_tasks.blocking_session_id has a value, you can use activity monitor to see what that process is doing.
To open activity monitor, right-click on the server name in SSMS' Object Explorer and choose Activity Monitor. The Processes and Resource Waits sections are the ones you want.
Since you're having issues deleting the record and recreating the table, have you tried updating the record?
Something like (changing "body" field name to whatever it is in the table):
update [u413].[replies] set body='' WHERE replyID=13461
Once you clear out the text from that single reply record you should be able to alter the data type of the column to set an upper bound. Something like:
alter table [u413].[replies] alter column body nvarchar(100)

What is the difference between drop and delete database?

What is the difference between drop and delete database?
Difference between DELETE and DROP commands
Delete: The DELETE command is used to
remove rows from a table. A WHERE
clause can be used to only remove some
rows. If no WHERE condition is
specified, all rows will be removed.
After performing a DELETE operation
you need to COMMIT or ROLLBACK the
transaction to make the change
permanent or to undo it. Note that
this operation will cause all DELETE
triggers on the table to fire.
Drop: The DROP command removes a table
from the database. All the tables'
rows, indexes and privileges will also
be removed. No DML triggers will be
fired. The operation cannot be rolled
back.
Simply: a DELETE command removes matching rows, a DROP command removes the entire table.
I know this is an old post, but I was looking for the answer myself, and since I believe the OP has asked about dropping or deleting the database, rather than tables or content, I thought I'd chip in.
Both will delete the database, but both could involve more than one step if you want to completely remove the database and associated artefacts.
DELETE
If you are using SQL Server Management Studio, you can delete the database by right clicking on the database and selecting Delete. The resulting dialog offers a couple of checkboxes :
'Delete backup and restore history information for databases'
'Close Existing connections'
If you don't tick 'Delete backup and restore history..' , those files will remain on the server unless you manually get rid of them.
'Close Existing connections' is a good idea, otherwise you may get an error telling you the database is still in use (even if it's just you, while you're trying to delete it)
DROP
The SQL Command 'DROP' alone will not remove everything. You will still need to also remove the backup history, and set the database to 'single user mode' - or it may complain the database is still in use, as above.
--Remove backup history
EXEC msdb.dbo.sp_delete_database_backuphistory #database_name = N'YourDBName'
GO
USE [master]
GO
--close all the open connections to your database
ALTER DATABASE [YourDBName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
USE [master]
GO
--remove the actual database
DROP DATABASE [YourDBName]
GO
Delete removes content and drop the structure of a database.
Delete removes content of table.Drop removes content and structure of table.Delete can be rolled back but Drop can not be rolled back
Suppose you are using MS SQL
Then if you want to delete the whole Table then you would use:
DROP TABLE MyTable
This would delete the whole table and its constraints
To delete any specific row you would use:
DELETE FROM MyTable WHERE id=5
This would delete the row with the id = 5
If no conditions are matched it would delete all rows
DROP removes the entire table and associated objects from the catalog, requiring you to create all the indexes and constraints from scratch.
Drop in a function that physically removes and particular table or a column. The table struction remails same. If you want to see the structure, you can write this
desc tablename; and the structure will be same after dropping the table.
Delete function permanantly deletes the table or a column, the structure of the table also.