Query to change table collation in SQL Server 2008 - sql-server

In my database, one table collation is different than all the other tables.
I would like to change that table collation to be the same as all other tables.
Now, I can change a table collation by using SSMS Design but I would like to use query to change collation. Currently, my one table collation is Thai_CI_AS and I want to change collation is SQL_Latin1_General_CP1_CI_AS.
It's not possible to drop the table because it already contains data.

Never a bad idea to consult the documentation. Guessing at the source data type and NULLability; you can fill in the table/column names:
ALTER TABLE dbo.TableName ALTER COLUMN ColumnName
NVARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL;
If you can't check the documentation, Management Studio will sometimes show you the smart way to do something (though it doesn't always choose to do things the best way). Go into the design screen, change the collation, and instead of clicking OK, click the Script button.

This is a valid solution that I applied and tested resetting collation on one of jira database tables.
-- CHANGED COLUMN COLLATION PROPERLY
ALTER TABLE [schemaName].[TableName]
ALTER COLUMN [columnName] [varchar](255)
COLLATE SQL_Latin1_General_CP437_CI_AI NOT NULL;
--Check string column collation for specified table
--Lists all string columns with respective collation
SELECT c.name,
c.collation_name
FROM SYS.COLUMNS c
JOIN SYS.TABLES t ON t.object_id = c.object_id
WHERE t.name = 'TableName'
and c.collation_name is not null

Related

Collation change accent sensitive column

Is there any way to make search query accent sensitive in one column of my table?
the column's and table's collation are in LATIN1_GENERAL_CS and I don't want to change the table.
How to change the values of my column that they are already with accent: Example replace "Systèmes" with Systemes ?
ALTER TABLE NameTable MODIFY COLUMN NameColumn varchar(40) COLLATE LATIN1_GENERAL_CS
Off course you can...
modify one column of your table
use the COLLATE operator in the query to retrieve data with a CI/CS or AI/AS (or much more)
ALTER TABLE <table_name>
ALTER COLUMN <columns_name> <data_type> COLLATE collation_name
or
SELECT *
FROM <table_name>
WHERE <columns_name> COLLATE Latin1_General_CI_AI = 'Système'

Azure SQL database table variable collation

Azure SQL Servers have a fixed collation of SQL_Latin1_General_CP1_CI_AS. I have an Azure SQL database with a collation of Latin1_General_CI_AS. I seem to be getting collation conflict errors when creating a table variable and joining to a database table. Here is the code:
DECLARE #resultingRoles TABLE ([MemberRoleName] NVARCHAR(256) NOT NULL PRIMARY KEY)
INSERT INTO #resultingRoles
SELECT DISTINCT([MemberRoleName]) FROM [RolesInRoles]
WHERE
[ApplicationName] = #applicationName AND
[MemberRoleName] IN (#role0,#role1,#role2)
WHILE (##ROWCOUNT>0)
BEGIN
INSERT INTO #resultingRoles
SELECT DISTINCT([roles].[TargetRoleName])
FROM [RolesInRoles] AS [roles]
INNER JOIN #resultingRoles sj ON sj.[MemberRoleName] = [roles].[MemberRoleName]
LEFT JOIN #resultingRoles lf on [roles].[TargetRoleName] = lf.[MemberRoleName]
WHERE lf.[MemberRoleName] IS NULL
AND [roles].[ApplicationName] = #applicationName
END
This results in the following error:
Cannot resolve the collation conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
I presume this is because the tabel variable column MemberRoleName is being created with the SQL Server collation NOT the database collation. My expectation was that the database collation would be used - am I wrong?
Is there any way to check the collation on a table variable?
Edit: I cannot change this SQL code to explicitly set the collation.
Try using
DECLARE #resultingRoles TABLE ([MemberRoleName] NVARCHAR(256) COLLATE Latin1_General_CI_AS NOT NULL PRIMARY KEY)

SQLServer 2005 does not do the right thing

I have a problem when trying with Like statement like this:
First I have the data sheet:
When I execute the Sql command it does not do what I want.
My syntax:
select * from tbUsers where nUserID like N'%p%';
It does not show any results. Although I know that 'Finds any values ​​that have' p 'in any position'
result picture:
my code to create table:
Create table tbUsers(
iIDUser int identity(1,1) not null primary key,
nUserID nvarchar(50) null,
nPassWord nvarchar(50) null,
dDate datetime null,
nName nvarchar(50) null
)
INSERT INTO tbUsers(nUserID,nPassword,nName) VALUES('phuc','123456', 'Phuc Nguyen')
INSERT INTO tbUsers(nUserID,nPassword) VALUES('ngocanh','123456')
INSERT INTO tbUsers(nUserID,nPassword) VALUES('long','123456')
INSERT INTO tbUsers(nUserID,nPassword) VALUES('long%ngocanh','123456')
INSERT INTO tbUsers(nUserID,nPassword) VALUES('phuc nguyen','123456')
Please help me. Thank you.
Hi your problem can be your collation if you need the Vietnamese collation for any reason you can alter your query to use the collation in your query like this one:
select *
from tbUsers
where nUserID collate SQL_Latin1_General_CP1_CI_AS like N'%p%';
If not my recommendation is to re-create the database using the collation SQL_Latin1_General_CP1_CI_AS since this query will be slow.
Also take in consideration if you have an index in the user column using double %% this will not let your index to be used. If you use only one % the index will be activated. Take a look of the execution plan to review this.
If want to stay with the Vietnamese collation maybe change the collation to the columns you need for this type of functionality. This will help you with the performance.
To change the collation of a column use
ALTER TABLE MyTable ALTER COLUMN Column1 [TYPE] COLLATE [NewCollation]
You can take a look to this question for more details
How to set collation of a column with SQL?
Since you are using Vietnamese collation you are not getting back the rows. You can specify the collation in your query quite easily though and it will return the rows you are looking for.
select *
from tbUsers
where nUserID collate SQL_Latin1_General_CP1_CI_AS like N'%p%';

SQL collating two tables, will it permanently change the collation?

for example, i'm trying to join the product sales table with the customer info table on two different databases of the same server and i end up getting the "Cannot resolve the collation conflict between Latin1_General_CI_AS... " error...
so i've been reading up about how collate DATABASE_DEFAULT will make the uniqueidentifier columns on two tables match and join together...but is the change temporary (during the query only) or will it actually alter the collation on the 2 tables?
thanks
SELECT V.PRODUCT, V.DESCRIPTION, A.NAMECUST, A.NAMECITY
FROM Warehouse.dbo.v AS V
INNER JOIN Maindata.dbo.Customerdata AS A
ON V.CUSTOMER_NUMBER = A.CUSTOMER_NUMBER COLLATE DATABASE_DEFAULT
When COLLATE is used in a query (not a CREATE/ALTER TABLE, CREATE/ALTER INDEX statement) it overrides the table-table (or database-default) collation with one used just for that query, it's saying "use this collation (comparison algorithm) when comparing values for this query only". It does not affect the underlying representation of data on disk or change any definitions (that's what ALTER is for).
Note that using COLLATE in a query is often a bad code-smell: if your database is designed with correct collation in the first place then this won't be necessary.

"Cannot resolve collation conflict" even after fixing the collation

The current database I'm using "PrimaryDatabase" has the collation "SQL_Latin1_General_CP1_CI_AS", while the "SecondaryDatabase" I'm trying to access has the collation "Arabic_CI_AS"
I changed the collation for the SecondaryDatabase and set it to " SQL_Latin1_General_CP1_CI_AS" and made sure it has been changed as well as in its tables.
However, when i run the query below I still get collation conflict.
select * from [MYSERVER].[SecondaryDatabase].[dbo].[SecondaryTableName]
where ltrim(rtrim([SecondaryTablename])) not in (select ltrim(rtrim(PrimaryFieldname)) from PrimaryTablename where PrimaryFieldName2=1)
One way to make your query work is to use COLLATE clause in order to apply a collation cast on both fields being involved in the predicate of the WHERE clause:
select *
from [MYSERVER].[SecondaryDatabase].[dbo].[SecondaryTableName]
where ltrim(rtrim([SecondaryFieldname])) COLLATE SQL_Latin1_General_CP1_CI_AS
not in (select ltrim(rtrim(PrimaryFieldname)) COLLATE SQL_Latin1_General_CP1_CI_AS
from PrimaryTablename
where PrimaryFieldName2 = 1)
The COLLATE clause applied to PrimaryFieldname might not be necessary, since this is the default collation of the corresponding database (so probably PrimaryFieldname already has this collation).
Another solution is to change the collation at field level, e.g.:
ALTER TABLE SecondaryDatabase
ALTER COLUMN SecondaryFieldname VARCHAR(50)
COLLATE SQL_Latin1_General_CP1_CS_AS NULL

Resources