Change Database Collation after migration? - sql-server

I have an MVC5 project and I populated my tables to the database via Entity Framework 6 - Code First migration. When looking to the tables, I ses that some characters do not displayed correctly and the Database Collation is SQL_Latin1_General_CP1_CI_AS instead of French_CI_AS.
1) What should be made in order to set the Database Collation while creating database via Code First? I found the following method below, but not sure if it is the best option for this purpose?
public override void Up()
{
Sql("ALTER DATABASE [YourDB] COLLATE [YourCollation]", suppressTransaction: true);
[...Your DB Objects Creation codes here...]
}
On the other hand, when using this script, I encounter "ALTER DATABASE failed. The default collation of database 'DbName' cannot be set to French_CI_AS" error.
2) Is it possible to change the Database Collation (via Code First or SQL) after adding some data to the related tables?
Any help would be appreciated...

It should be possible to change the collation even after adding data. I guess your problem comes from the fact that you need to put the database in single-user mode while you are executing the collation change. The database must be locked to prevent other connections from using it. After you finish you restore the multi-user mode.
If this is your case you should be getting this error in addition to the one you show in your question:
The database could not be exclusively locked to perform the operation.
The migration code to fix it:
public override void Up()
{
Sql("ALTER DATABASE [YourDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;");
Sql("ALTER DATABASE [YourDB] COLLATE [YourCollation];");
Sql("ALTER DATABASE [YourDB] SET MULTI_USER;");
[...Your DB Objects Creation codes here...]
}
I think you should remove the supressTransaction parameter. You should probably run this operation in a single transaction, in case some step fails.

Related

Sql Azure - remove a secondary server from geo-replication

I'm trying to remove a secondary database from geo-replication:
alter database DBNAME
remove secondary on server SERVERNAME
However, every time I run that I get:
Msg 45182, Level 16, State 1.
Database 'DBNAME' is busy with another operation. Please try your operation later. (Line 1)
Can I do this without taking the database offline?
Please take in consideration that ALTER statement should be executed on the master database on which the primary database server is located.

Change database options during EF migration

We have some POCO classes and migrations enabled for my dataaccess layer we have created a initial migration to - remark we use the CreateDatabaseIfNotExist db initialization.
But in the database I would like have a MessageBody field that uses SQL Filestream, because the limitation on EF for Filestream - we try to do it manually in the migration script.
There we execute the following sql command.
Sql("alter table [msg].[Message] add [MessageBody] varbinary(max) FILESTREAM not null");
But I have to set the filestream options
So I would like to execute the following command during / before the migration.
ALTER DATABASE CURRENT SET FILESTREAM ( NON_TRANSACTED_ACCESS = FULL)
But when adding this bedore the creation of the tables I get the error: ALTER DATABASE statement not allowed within multi-statement transaction.
What's the best way to adapt Database options when you want to create the database automatically? Is it possible to intercept the migration process to execute some sql before the process executes the acutal migrations?
To fix error that occured to you you only need to invoke Sql method with additional bool parameter set to true:
Sql("alter table [msg].[Message] add [MessageBody] varbinary(max) FILESTREAM not null", true);
This will cause that your query will be executed in separate transaction.

SQL Server tells me database is in use but it isn't

SQL Server keeps telling me a database is in use when I try to drop it or restore it, but when I run this metadata query:
select * from sys.sysprocesses
where dbid
in (select database_id from sys.databases where name = 'NameOfDb')
It returns nothing.
Sometimes it will return 1 process which is a CHECKPOINT_QUEUE waittype. If I try to kill that process, it won't let me (cannot kill a non-user process).
Anyone have any idea what's wrong?
i like this script. Do not struggle with killing..
use master
alter database xyz set single_user with rollback immediate
restore database xyz ...
alter database xyz set multi_user
I was having the same issue when trying to restore a database from a backup. The solution for me was to ensure that I checked "Overrite the existing database(WITH REPLACE)" and "Close existing connections to destination database" in the Options page BEFORE doing the restore. Here is a screenshot below.
There could be lots of things blocking your database. For example, if you have a query window opened on that database, it would be locked by you. Not counting external accesses, like a web application on IIS.
If you really wanna force the drop on it, check the close existing connections option or try to manually stop SQL Server's service.

DML operation with out logging - SQL Server

Is there any way that we can do DML operation with out logging it into log file?
For example, when I am inserting a row in database, this operation will be logged in log file irrespective of using transaction or not. But I don't want to log this operation in the log file.
No. Never. Not possible.
Every operation is logged for a reason: what if it fails halfways through? Server crashes? etc etc
In summary: the A, C and D in ACID
If you don't want this, then using I would really consider using non-ACID NoSQL alternatives.
SQL Server will always write an insert to the log file. It needs that information to recover a database in a consistent state when the server resets.
You can change to impact logging has by choosing the recovery model:
alter database YourDb set recovery { FULL | BULK_LOGGED | SIMPLE }
In simple mode, SQL Server logs just running transactions, and starts reusing parts of the log that are no longer needed. In simple mode, the log file typically remains small.
If you want to get rid of logs after an insert operation, you can use:
alter database YourDb set recovery simple with no_wait
dbcc shrinkfile(YourDbLog, 1)
alter database YourDb set recovery <<old model here>>
Note that this gets rid of all logs. You can only use the restore the last full backup after running this command.

Why must QUOTED_IDENTIFIER be on for the whole db if you have an indexed view?

Yesterday I added some indexes on a view in my MSSQL 2008 db. After that it seems like all the store procedures need to run with QUOTED_IDENTIFIER set to ON, even those that don't use the view in question.
Why is it so? Is this something I can configure on the db or do I have to update all my stored procedures to set the QUOTED_IDENTIFIER to ON? I think it is rather weird that this is required for the stored procedures not using the view.
Do these stored procedures relate to the base table(s) that the view is based upon? To quote from Creating Indexed Views:
After the clustered index is created,
any connection that tries to modify
the base data for the view must also
have the same option settings required
to create the index. SQL Server
generates an error and rolls back any
INSERT, UPDATE, or DELETE statement
that will affect the result set of the
view if the connection executing the
statement does not have the correct
option settings. For more information,
see SET Options That Affect Results.
And it's kind of obvious, when you think about it - you're potentially going to be updating the contents of the view whenever you touch these base tables, and so you inherit the same responsibilities as when you created the index.
You can set the defaults at multiple levels:
Any application can explicitly override any default settings by executing a SET statement after it has connected to a server. The SET statement overrides all previous settings and can be used to turn options on and off dynamically as the application runs. The option settings are applicable only to the current connection session.
OLE DB and ODBC applications can specify the option settings that are in effect at connection time by specifying option settings in connection strings. The option settings are applicable only to the current connection session.
SET options specified for a SQL Server ODBC data source by using the ODBC application in Control Panel or the ODBC SQLConfigDataSource function.
Default settings for a database. You can specify these values by using ALTER DATABASE or the Object Explorer in SQL Server Management Studio.
Default settings for a server. You can specify these values by using either sp_configure or Object Explorer in SQL Server Management Studio to set the server configuration option named user options.

Resources