How can I convert "SQL_Latin1_ General" Collate Using an SSIS Package? - sql

We've just noticed 2 of our servers have been set up using SQL_Latin1_General_CP1_CI_AS and Latin1_General_CI_AS.
I've created a script which compares two sources of data again each other (as it's a simple SELECT statement I haven't included it, it uses the same columns but from different sources) when I tried to union them together I received the collate error.
Msg 468, Level 16, State 9, Line 2
Cannot resolve the collation conflict between
"SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AS" in the UNION operation.
One of the sources is a table which is being populated by an SSIS package, is there a way of adapting the SSIS project to convert the "SQL_Latin1_General_CP1_CI_AS" format to "Latin1_General_CI_AS" before it's sent to the destination table?
Thanks!

You can use the sentence COLLATE Latin1_General_CI_AS after each column in the table that use SQL_Latin1_General_CP1_CI_AS like this.
SELECT COLUMN_A COLLATE Latin1_General_CI_AS AS COL1
FROM TABLE

Your error message looks like your UNION is in a single SQL statement?
e.g SELECT ... UNION ... SELECT
As Shiva described, within your SSIS Data Flow, you can use two (or more) OLE DB Source objects and combine them with a "Union All" transformation. Each OLE DB Source object will have just a single SELECT with no UNION clause. This design also has advantages in design/maintenance (unions on column names, no need to fill every column from every source) and runtime throughput.
I think you also need to use this technique on the OLE DB Source objects.
http://blog.stevienova.com/2009/04/16/ssis-pulling-data-from-a-non-default-collation-db-to-a-default-collation-db/

Related

Ignore Case Sensitivity While Querying Data

I have a database in Azure SQL Server with collation as 'SQL_Latin1_General_CP1_CS_AS' and in that i have table that has two columns
CREATE TABLE DBO.TABLE1(
[ROWID] [numeric](16, 0) IDENTITY(1,1) NOT NULL,
[CODE] [varchar](10) NOT NULL,
)
Now below query works fine in Azure SQL ignoring the case sensitivity of column names
SELECT rowID, coDE FROM DBO.TABLE1
SELECT rowid, code FROM DBO.TABLE1
But when i create the database on a Sql Server inside Azure VM (IaaS solution) with same collation setting: 'SQL_Latin1_General_CP1_CS_AS' then above queries are not working at all its throwing below error:
Msg 207, Level 16, State 1, Line 1
Invalid column name 'rowid'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'code'.
How do i suppress this case sensitivity of column name while querying tables in Sql server on Azure VM.
Please advice.
Azure SQL Database always uses contained database collation, which allows you to have a case-sensitive database without having a case-sensitive catalog (yuck).
In a contained database, the catalog collation
Latin1_General_100_CI_AS_WS_KS_SC. This collation is the same for all
contained databases on all instances of SQL Server and cannot be
changed.
In SQL Sever on an Azure VM you can get the same behavior by using a contained database. Your database collation (and the default collation of all your table columns) can be SQL_Latin1_General_CP1_CS_AS, but your table names, column names, proc names, etc will use the case-insensitive Latin1_General_100_CI_AS_WS_KS_SC.
SQL_Latin1_General_CP1_CS_AS is case-sensitive, compare to SQL_Latin1_General_CP1_CI_AS which is case-insensitive. It's better to change your DB collation.

Using COLLATE DATABASE_DEFAULT when querying the UNION when the table headers are unknown?

I am currently using code of the form
SELECT * FROM ##Temp1
UNION
SELECT * FROM ##Temp2
which (because the temporary tables are populated from tables in 2 different databases, which each use a different collation) results in the error message
Cannot resolve the collation conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in the UNION operation.
Until now, when faced with an error such as this, I have been using the COLLATE DATABASE_DEFAULT method, which has been possible because the headings contained within the tables have been constant.
However, I am now faced with a collation conflict between 2 tables where the table headings are not constant. How might I resolve this issue?
One possible solution that I can think of is to loop through the table headers for ##Temp1 in the tempdb.dbo table and generate a string dynamically which specifies the column headings used in the temporary tables. However, this seems unneccessarily clumsy.

Linked server reference "Invalid Column Name"

In SSMS 2012, I have created a linked server in SERVERA to SERVERB from which I have successfully written queries to multiple tables within the DBB database using a four part reference.
When I try to reference the 'Charge' table in the 'DBB' database with a simple select statement:
SELECT * FROM [SERVERB].[DBB].dbo.Charge
I get the following message:
Msg 207, Level 16, State 1, Line 1 Invalid column name 'charge_type'.
This column exists in the DBB database as 'Charge_Type', however, the collation of SERVERB is case insensitive, whereas the collation of SERVERA is case sensitive (which is where, I believe, my problem lies).
Does anyone have experience with this issue?
(For the people who might end up here)
You can change the collation on the fly. In this case, you have to write the name of the column names in the select query. What I mean is,
rather than writing query like this:
SELECT * FROM [SERVERB].[DBB].dbo.Charge
write the query like this:
SELECT Charge_Col1, Charge_Col2, Charge_Type COLLATE Latin1_General_CI_AS FROM [SERVERB].[DBB].dbo.Charge
There is another post similar to this: how we can select two columns having different collation

How to use EXCEPT clause in multiple databases

I have a query with an except clause. Underneath the except, my 2nd query is coming from a different database than the one that the first query is using.
It looks something like this
SELECT field1 as a
FROM table 1
EXCEPT
USE differentdb
SELECT field2 as a
FROM table 2
I have also tried this
SELECT field1 as a
FROM table 1
EXCEPT
USE differentdb
SELECT field2 as a
FROM differentdb.dbo.table2
I realize that this is not allowed in SQL because I get the following error:
Msg 468, Level 16, State 9, Line 1 Cannot resolve the collation
conflict between "SQL_Latin1_General_CP1_CI_AS" and
"Latin1_General_CI_AS" in the equal to operation.
I am wondering if there is another way to write this query and accomplish a cross-db EXCEPT clause.
Change the collation of column on the fly like:
SELECT field1 COLLATE SQL_Latin1_General_CP1_CI_AS as a
FROM table 1
EXCEPT
SELECT differentdb.SchemaName.field2 as a
FROM table 2
Us can use collate clause to convert collation from other database.
SELECT field2 collate SQL_Latin1_General_CP1_CI_AS as a
FROM table 2
Here you should use correct collation - because it is not enough information what is collation of your first and second databases.
Or you can simply use
SELECT field2 collate database_default as a
FROM table 2
This will cause the collate clause to inherit the collation of the current database

SQL Server 2005 date comparison - collation issues

In my DB, I have a table that was created from an Excel sheet, via a Linked Server option.
I am now trying to compare its contents versus one of my main tables.
The tables I am comparing are in the same database.
There is a date column in both tables, both types are datetime and have Collation of SQL_Latin1_General_CP1_CI_AS, the same as the DB.
The server collation is Latin1_General_CI_AS
However when I try to run a query comparing the dates between the tables, I get the error:
Cannot resolve the collation conflict between
"Latin1_General_CI_AS" and
"SQL_Latin1_General_CP1_CI_AS" in the
equal to operation.
I have tried with and without the COLLATE option, using both collation settings.
My query is:
select * , hxl.holiday_dt,
datediff(d, h.holiday_dt collate SQL_Latin1_General_CP1_CI_AS,
hxl.holiday_dt collate SQL_Latin1_General_CP1_CI_AS)
from holiday h, Holiday_XL hxl
where h.currency_cd=hxl.currency_cd
In fact any query involving both tables gives exactly the same collation error, eg this one:
select count(*)
from Holiday_XL c
where c.currency_cd in (select distinct h.currency_cd from holiday h)
Thanks in advance for any thoughts.
Regards,
Chris
The error is being reported on the currency comparison h.currency_cd=hxl.currency_cd, not on datediff, so try force collation on the currencies.
Collation is only relevant for character (char, varchar, nvarchar) and text types.
Under the Collation and give the collation table level there are lot of tips and code available in net search with topic of collation.
Still if you have problem. Insert the content of the excel in to #table or permenant table and provide Collation to that table while selecting for comparison