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

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.

Related

SQL Server Irish FADA not displaying correctly

In SQL by default it was using SQL_Latin1_General_CP1_CI_AS
From my backup SQL DB, I change collation into Latin1_General_100_CI_AS_SC_UTF8
However when I query, the text show as An Phr�omhsr�id Uachtarach
Changing the collation of an existing database doesn't change the collation of existing objects within it, only new ones. For existing tables you'll need to update the collation on each table column separately.
ALTER TABLE MyTable
ALTER COLUMN MyCol VARCHAR(100) COLLATE Latin1_General_100_CI_AS_SC_UTF8;
Note that could be a blocking operation which could be an issue in large tables. To get around that you can create a new table with the correct collation, copy the data in, delete the old table, and rename the new table to the old name.

"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

SQL server key violation due to case insesitivity

I m having a table in which a primary key is there with 2 columns(CODE nvarchar,VALUE nvarchar).This table contains the values in the Key columns as (X8900,A) but when I try to insert a new value as (X8900,a) ,its giving error message “primary key violation”.
Why its giving this error,if case is different for values column and is there any solution for this in order avoid the error ?
You can specify if SQL Server should be case sensitive or not using collation. In this instance the column must have a case sensitive collation in order for you to be able to specify any type of unique constraint on it. For example, the first example will fail whereas the second will work, notice the CI and CS for case insensitive and sensitive.
CREATE TABLE test1 (
col1 varchar(20) COLLATE Latin1_General_CI_AS PRIMARY KEY
)
INSERT INTO test1 VALUES ('ASD')
INSERT INTO test1 VALUES ('asd')
CREATE TABLE test2 (
col1 varchar(20) COLLATE Latin1_General_CS_AS PRIMARY KEY
)
INSERT INTO test2 VALUES ('ASD')
INSERT INTO test2 VALUES ('asd')
Collation can be set at the column or database level. If set at database level then all character columns without a collation specified adopt the database collation.
You have to check the collation of your database. If you have a case insensitive collation, 'A' == 'a'. If you need to maintain difference between cases, you can either change the collation to a case sensitive collation, or you could cast the strings to varbinary. A binary representation differentiates between cases.
Collations can be set at the server level (i.e what databases default to) and at the database level (overriding the server collation). At an even more granular level, you can set collation on individual columns if you want/need. Here are a few articles to look at:
https://msdn.microsoft.com/en-us/library/hh230914.aspx#TsqlProcedure
https://msdn.microsoft.com/en-us/library/ms144250%28v=sql.105%29.aspx
Here are a few SQL snippets you can run to view your current server collation, as well as the default collations on each database
SELECT CONVERT (varchar, SERVERPROPERTY('collation'));
SELECT name, collation_name FROM sys.databases;

Check if the nullable column is sparsed or not query in SQL Server

How to check if a column has been set as Sparse or not?
I know how to add the sparse while creating or altering tables
ALTER TABLE T1
ALTER COLUMN C1 VARCHAR(50) SPARSE NULL
GO
And it is possible to execute sparse query for the sparsed column. But not sure about any harms it may cause. just wondering is there any way to check is the column has been set as sparsed or not?
Basically, I am trying to create a script which will determine the compatibility level of sql server and if it supports Sparse then it will check "Is a column has already been sparsed or not" and if not then it required to alter the column and add sparse. It will be better if it is possible to determine the NULL percentage.
Try this :
Select Name, is_sparse from sys.Columns where object_id = object_id('YourTable')

Query to change table collation in SQL Server 2008

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

Resources