We are facing issue in removing SQL Filetable. Whenever I run
select * from <MY SQL FILE TABLE>
I get this error message
A transport-level error has occurred when receiving results from the server. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)
When I see sp_readerrorlog, I see this message
SQL Server internal error. FILESTREAM manager cannot continue with current command.
When I run this query
ALTER DATABASE XXX
REMOVE FILEGROUP FStream1
I get this message:
The filegroup 'FStream1' cannot be removed because it is not empty.
I tried to delete the SQL Filetable
drop table `SQLFiletable_bck`
but I get this error :
The FILESTREAM filegroup 'FileStreamGroup1' has no files assigned to it. FILESTREAM data cannot be populated on this filegroup until a file is added.
Then I tried this option
ALTER TABLE SQLFiletable_bck
SET (FILESTREAM_ON = "NULL")
but I get this error
Cannot drop FILESTREAM filegroup or partition scheme since table 'SQLFiletable_bck ' has FILESTREAM columns.
I was not able to drop the SQL File table
Can anyone tell me any way to forcefully cleanup FileStream and its FileGroup in SQL Server 2012?
In order to fix
ALTER TABLE TableName SET (FILESTREAM_ON = "NULL")
you have to drop the column(s) using FILESTREAM. In order to be able to do that, you probably have to drop some constraint, too:
ALTER TABLE TableName DROP CONSTRAINT DF_TableName_ColumnName;
ALTER TABLE TableName DROP COLUMN ColumnName;
ALTER TABLE TableName SET (filestream_on = "NULL");
ALTER DATABASE DatabaseName REMOVE FILE 'DatabaseFileName');
ALTER DATABASE DatabaseName REMOVE FILEGROUP "FilegroupName";
Related
A little challenge for the MS Sql Server experts out there...
I have a database on a SQL Server 2008 R2 server.
I have created a schema named MPP and a handful of table for this schema.
The tables were originally created in the default dbo schema and then moved to the new schema using the sp_changeobjectowner procedure. The tables were however created and dropped a few times before I got it to work as I wanted.
To the problem... Whenever I now create a new table, regardless in the default dbo schema or I get one error message per table in the new schema referring to an error in the sp_changeobjectowner procedure:
CREATE TABLE dbo.test (d INT);
Msg 15001, Level 16, State 1, Procedure sp_changeobjectowner, Line 64
Object 'ASBJOR.TEST_TABELL' does not exist or is not a valid object for this operation.
There is a database user named ASBJOR, but no schema.
If I add a new table to the MPP schema the number of error messages will increase and one of the messages refers to the new table.
I've tried to create a new table in the default dbo schema and move it to the MPP schema using the ALTER SCHEMA MPP TRANSFER... command, but new table still appears in the error messages.
I've looked through the sys.objects, sys.tables, sys.schemas and sys.database_principals tables but I can't find anything wrong.
Any ideas what could cause this error message or where I can look for more hardcore details in the database?
You should never use sp_changeobjectowner - it's been deprecated since 2005. Always use ALTER SCHEMA ... TRANSFER.
As for the error, check for a DDL trigger in that database:
SELECT * FROM sys.triggers WHERE parent_class = 0;
Then check to see what those triggers are doing.
I am trying to execute the following query on two different databases with difent collations
select * from sourcedb.DBO.PKtable
except
select * from destinationdb.DBO.PKtable
It is clear that both the tables have the same columns and the primary key
But when executing, encountered the following exception
Msg 468, Level 16, State 9, Line 17
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CS_AS" in the EXCEPT operation.
I cannot use COLLATE keyword because.. I will be using the above query at runtime and the table name and columns vary, hence cannot predict the columns of the table.
I have tried to change the collation of the destination database to same as the source database using the following command
ALTER DATABASE destinationDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE destinationDB COLLATE <<sourceCollation>>;
ALTER DATABASE destinationDB SET MULTI_USER
The collation is set to the database and I can see it from the sys tables.
Even then when I execute the query mentioned above, getting the same error
EDIT1: Basically I'm trying to get the records which have the same primary key but difference in the row.
Another possible workaround (apart from dynamic sql) might be to use a temporary table. (This may suit if this is a one off type of operation).
-- create empty #PKTable with required columns and collation.
select * INTO #PKTable from sourcedb.DBO.PKtable where 1=0
-- fill table with data
insert #PKTable select * from destinationdb.DBO.PKtable
-- compare
select * from sourcedb.DBO.PKtable
except
select * from #PKTable
-- remove temp table
drop table #PKTable
I have tried the FILESTREAM feature for MSSQL (2008R2 Data Center) on a local database, to experiment. The real database is running on a server. I have setup the whole FILESTREAM, using this query:
/* CREATE FILESTREAM AND FILESTREAM TABLE */
USE [master]
GO
ALTER DATABASE SenONew
ADD FILEGROUP [FileStream]
CONTAINS FILESTREAM
GO
ALTER DATABASE SenONew
ADD FILE
(
NAME = 'fsSenONew',
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\SenONew.ndf'
)
TO FILEGROUP [FileStream]
GO
USE [SenONew]
GO
CREATE TABLE Filestore(
FileID int PRIMARY KEY,
RowID uniqueidentifier ROWGUIDCOL NOT NULL UNIQUE DEFAULT NEWSEQUENTIALID(),
FileDescr nvarchar(max),
FileIndex varbinary(max) FILESTREAM NULL)
GO
And I was experimenting with adding a few files then deleting them.
Now since this was only meant to be an experiment, I also want to get rid of it. I'm using my local server for the development of the database that will be used on the real server, thus I'm creating BackUp's on my local server then Restore this on the real server, so it gets updated (software is in development, so the database structure changes much as well as the data and I need to do a full restore to the real server, where the software is being tested on).
After hours of searching, I couldn't find anything on my problem.
I understand that I need to:
Remove the database table storing the FILESTREAM information
I need to remove the FILE of the FILESTREAM
Remove the filegroup
So I'm using this query to get rid of everything I set up in the first place:
/* DROP FILESTREAM TABLE AND FILEGROUP */
USE SenONew
DROP TABLE Filestore
GO
ALTER DATABASE SenONew
REMOVE FILE fsSenONew
ALTER DATABASE SenONew
REMOVE FILEGROUP [FileStream]
GO
So I do everything as I should and it completes without error as well. So when I enter my filegroups, files and my file location, I see they are all completely removed:
But when I do a BACKUP of my local database (which include the deleted FILESTREAM, file path and filegroup) and try to restore the server with it, I get errors.
SQL to create a BACKUP:
/* CREATE BACKUP OF DATABASE WITHIN CURRECT CONNECTION */
DECLARE #FileName2 nvarchar(250)
SELECT #FileName2 = (SELECT 'C:\SenO BackUp\' + convert(nvarchar(200),GetDate(),112) + ' SenONew.BAK')
BACKUP DATABASE SenONew TO DISK=#FileName2
GO
Then do the Restore on the server:
/* CREATE RESTORE OF DATABASE WITHIN REAL SERVER CONNECTION */
use master
alter database SenONew set offline with rollback immediate;
DECLARE #FileName2 nvarchar(250)
SELECT #FileName2 = (SELECT '' + convert(nvarchar(200),GetDate(),112) + ' SenONew.BAK')
RESTORE DATABASE SenONew
FROM DISK = #FileName2
alter database SenONew set online with rollback immediate;
I get the following error:
*(Msg 5121, Level 16, State 2, Line 7
The path specified by "C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\SenONew.ndf" is not in a valid directory.
Msg 3156, Level 16, State 3, Line 7 File 'fsSenONew' cannot be restored to 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\SenONew.ndf'. Use WITH MOVE to identify a valid location for the file.
Msg 3119, Level 16, State 1, Line 7 Problems were identified while planning for the RESTORE statement. Previous messages provide details.
Msg 3013, Level 16, State 1, Line 7 RESTORE DATABASE is terminating abnormally. )*
I deleted the .ndf FILESTREAM location, why is it a specified path? Also, why is fsSenONew trying to restore? I can't get my head around it. Are there paths internally that I need to delete?
You can check:
SELECT * FROM SenONew.sys.data_spaces WHERE name = 'FileStream'
it should return 0 rows.
There is a procedure to remove FILESTREAM features from a SQL Server 2008 database :
ALTER TABLE Filestore DROP column FileIndex
GO
ALTER TABLE Filestore SET (FILESTREAM_ON="NULL")
GO
ALTER Database SenONew REMOVE FILE fsSenONew
GO
ALTER Database SenONew REMOVE FILEGROUP [FileStream]
GO
as described in this article. But the steps you did should do the same thing.
Your problem is certainly strange, but I suggest that you try using following
USE SenONew
EXEC Sp_help
EXEC Sp_helpfile
EXEC Sp_helpfilegroup
You may find something suspicious there like another table using that FILEGROUP.
I have done exactly the steps you describe and cannot reproduce your problem. Check how your Restore database screen looks like.
1.Remove the FILESTREAM attribute from columns and tables. You'll need to move data to a new column.
ALTER TABLE MyTable
ADD FileData varbinary(max) NULL;
GO
update MyTable
set FileData = FileStreamData
GO
ALTER TABLE MyTable
DROP column FileStreamData
GO
ALTER TABLE MyTable SET (FILESTREAM_ON="NULL")
GO
EXEC sp_RENAME 'MyTable.FileData', 'FileStreamData', 'COLUMN'
GO
2.Remove files from the FILESTREAM and drop the FILE and FILESTEAM.
ALTER DATABASE [MyDatabase] SET RECOVERY Simple
GO
EXEC SP_FILESTREAM_FORCE_GARBAGE_COLLECTION
ALTER DATABASE [MyDatabase] REMOVE FILE [MyFile]
GO
ALTER DATABASE [MyDatabase] REMOVE FILEGROUP [MyFileGroup]
GO
ALTER DATABASE [MyDatabase] SET RECOVERY FULL
GO
This is my script that worked for me. It was a command missing, to empty the file:
ALTER TABLE FilesTable DROP column FileContent
GO
ALTER TABLE FilesTable SET (FILESTREAM_ON="NULL")
GO
USE mydbname
GO
DBCC SHRINKFILE (N'filestreamfile', EMPTYFILE)
GO
EXEC sp_filestream_force_garbage_collection #dbname = N'mydbname'
ALTER Database mydbname REMOVE FILE filestreamfile
GO
ALTER Database mydbname REMOVE FILEGROUP FILESTREAMGROUP
GO
IF COL_LENGTH('FilesTable','FileContent') IS NULL
BEGIN
ALTER TABLE FilesTable ADD FileContent [varbinary](max) NULL
END
GO
Alter Collation
I need to change the collation of one of our databases on a particular server from Latin1_General_CI_AS to SQL_Latin1_General_CP1_CI_AI so that it matches the rest of our databases.
The Problem
However, when I attempt to do this, I get the following error:
ALTER DATABASE failed. The default collation of database 'XxxxxXxxxxx' cannot be set to SQL_Latin1_General_CP1_CI_AI. (Microsoft SQL Server, Error: 5075)
My Research
My googling on the topic has revealed a number of articles which indicate that I need to export all the data, drop the database, re-create it with the correct collation, then re-import the data.
For example: Problem with database collation change (SQL Server 2008)
Obviously this is a significant task, especially since primary-foreign key relationships must be preserved, and our database is quite large (over ten million data rows).
My Question
Is there a way to change the collation of an existing SQL Server 2012 database which does not require exporting and re-importing all the data?
Alternatively, is there some tool or script(s) which can automate this process in a reliable manner?
The following works for me on SQL Server 2012:
ALTER DATABASE CURRENT COLLATE SQL_Latin1_General_CP1_CI_AI;
The accepted answer in the linked question is not entirely correct, at least not for SQL Server 2012. It says:
Ahh, this is one of the worst problems in SQL Server: you cannot change the collation once an object is created (this is true both for tables and databases...).
But I was just able to change the default collation and I have tables that are populated. The MSDN page for ALTER DATABASE states in the "Remarks" section, under "Changing the Database Collation":
Before you apply a different collation to a database, make sure that the following conditions are in place:
You are the only one currently using the database.
No schema-bound object depends on the collation of the database.
If the following objects, which depend on the database collation, exist in the database, the ALTER DATABASE database_name COLLATE statement will fail. SQL Server will return an error message for each object blocking the ALTER action:
User-defined functions and views created with SCHEMABINDING.
Computed columns.
CHECK constraints.
Table-valued functions that return tables with character columns with collations inherited from the default database collation.
So, I would suggest making sure that the database is in Single-User mode, and that if you have any of those four items, that you:
drop them
change the collation
and then re-add them
BUT, at that point all that has been changed is the Database's default Collation. The Collation of any existing columns in user tables (i.e. non-system tables) will still have the original Collation. If you want existing string columns -- CHAR, VARCHAR, NCHAR, NVARCHAR, and the deprecated TEXT and NTEXT -- to take on the new Collation, you need to change each of those columns individually. And, if there are any indexes defined on those columns, then those indexes will need to be dropped first (disabling is not enough) and created again after the ALTER COLUMN (other dependencies that would prevent the ALTER COLUMN would have already been dropped in order to get the ALTER DATABASE to work). The example below illustrates this behavior:
Test Setup
USE [tempdb];
SET NOCOUNT ON;
CREATE TABLE dbo.ChangeCollationParent
(
[ChangeCollationParentID] INT NOT NULL IDENTITY(1, 1)
CONSTRAINT [PK_ChangeCollationParent] PRIMARY KEY,
ExtendedASCIIString VARCHAR(50) COLLATE Latin1_General_CI_AS NULL,
UnicodeString NVARCHAR(50) COLLATE Latin1_General_CI_AS NULL
);
CREATE TABLE dbo.ChangeCollationChild
(
[ChangeCollationChildID] INT NOT NULL IDENTITY(1, 1)
CONSTRAINT [PK_ChangeCollationChild] PRIMARY KEY,
[ChangeCollationParentID] INT NULL
CONSTRAINT [FK_ChangeCollationChild_ChangeCollationParent] FOREIGN KEY
REFERENCES dbo.ChangeCollationParent([ChangeCollationParentID]),
ExtendedASCIIString VARCHAR(50) COLLATE Latin1_General_CI_AS NULL,
UnicodeString NVARCHAR(50) COLLATE Latin1_General_CI_AS NULL
);
INSERT INTO dbo.ChangeCollationParent ([ExtendedASCIIString], [UnicodeString])
VALUES ('test1' + CHAR(200), N'test1' + NCHAR(200));
INSERT INTO dbo.ChangeCollationParent ([ExtendedASCIIString], [UnicodeString])
VALUES ('test2' + CHAR(170), N'test2' + NCHAR(170));
INSERT INTO dbo.ChangeCollationChild
([ChangeCollationParentID], [ExtendedASCIIString], [UnicodeString])
VALUES (1, 'testA ' + CHAR(200), N'testA ' + NCHAR(200));
INSERT INTO dbo.ChangeCollationChild
([ChangeCollationParentID], [ExtendedASCIIString], [UnicodeString])
VALUES (1, 'testB ' + CHAR(170), N'testB ' + NCHAR(170));
SELECT * FROM dbo.ChangeCollationParent;
SELECT * FROM dbo.ChangeCollationChild;
Test 1: Change column Collation with no dependencies
ALTER TABLE dbo.ChangeCollationParent
ALTER COLUMN [ExtendedASCIIString] VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL;
ALTER TABLE dbo.ChangeCollationParent
ALTER COLUMN [UnicodeString] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL;
ALTER TABLE dbo.ChangeCollationChild
ALTER COLUMN [ExtendedASCIIString] VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL;
ALTER TABLE dbo.ChangeCollationChild
ALTER COLUMN [UnicodeString] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL;
SELECT * FROM dbo.ChangeCollationParent;
SELECT * FROM dbo.ChangeCollationChild;
The ALTER COLUMN statements above complete successfully.
Test 2: Change column Collation with dependencies
-- First, create an index:
CREATE NONCLUSTERED INDEX [IX_ChangeCollationParent_ExtendedASCIIString]
ON dbo.ChangeCollationParent ([ExtendedASCIIString] ASC);
-- Next, change the Collation back to the original setting:
ALTER TABLE dbo.ChangeCollationParent
ALTER COLUMN [ExtendedASCIIString] VARCHAR(50) COLLATE Latin1_General_CI_AS NULL;
This time, the ALTER COLUMN statement received the following error:
Msg 5074, Level 16, State 1, Line 60
The index 'IX_ChangeCollationParent_ExtendedASCIIString' is dependent on column 'ExtendedASCIIString'.
Msg 4922, Level 16, State 9, Line 60
ALTER TABLE ALTER COLUMN ExtendedASCIIString failed because one or more objects access this column.
ALSO, please be aware that the Collation of some string columns in database-scoped system catalog views (e.g. sys.objects, sys.columns, sys.indexes, etc) will change to the new Collation. If your code has JOINs to any of these string columns (i.e. name), then you might start getting Collation mismatch errors until you change the Collation on the joining columns in your user tables.
UPDATE:
If changing the Collation for the entire Instance is the desire, or an option, then there is an easier method that bypasses all of these restrictions. It is undocumented and hence unsupported (so if it doesn't work, Microsoft isn't going to help). However, it changes the Collation at all levels: Instance, all Database's, and all string columns in all User Tables. It does this, and avoids all of the typical restrictions, by simply updating the meta-data of the tables, etc to have the new Collation. It then drops and recreates all indexes that have string columns. There are also a few nuances to this method that might have impact, but are fixable. This method is the -q command-line switch of sqlservr.exe. I have documented all of the behaviors, including listing all of the potentially affected areas by doing such a wide-sweeping Collation change, in the following post:
Changing the Collation of the Instance, the Databases, and All Columns in All User Databases: What Could Possibly Go Wrong?
For anyone else stumbling to this problem, the solution is to set DB in single_user mode before change the collation and then set again the multi_user mode after it.
Make sure to not close the connection before setting the multi_user mode!
/* block all other users from connecting to the db */
ALTER DATABASE YorDbName SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
/* modify your db collate */
ALTER DATABASE CURRENT COLLATE SQL_Latin1_General_CP1_CI_AI;
/* allow again all other users to connect to the db */
ALTER DATABASE YorDbName SET MULTI_USER;
When I run this statement in SQL Server:
USE [master]
GO
ALTER DATABASE <DBName> ADD FILEGROUP <[FGName]>
Where is the corresponding .ndf file created on disk?
When I run that query, it's successful and I am able to find the new file group being added to the sys.filegroups table.
But when I run
select * from sys.database_files
I am not able to find the files created for the new file group. I couldn't find it in the disk as well. What am I doing wrong?
Could somebody help with this..?
Try this:
In SQL Server you will have to explicitly add the .ndf files to the different filegroups. If you dont mention any filegroup then by default it will be added to primary filegroup.
So whenever you add a filegroup it is just a logical name and it does not have any physical location.
use yourDBname
select * from sys.database_files
ALTER DATABASE yourDBname ADD FILE (NAME = name1, FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\DB11.ndf', SIZE=100MB, MAXSIZE=500GB, FILEGROWTH=50);
ALTER DATABASE yourDBname ADD FILEGROUP BusyTables
select * from sys.database_files