I am trying to compare data results from views on a test instance and on a live instance. Both instances are on the same server.
I have created a link between them both so I can query between them, but I am receiving a collation error - Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AI" in the EXCEPT operation.
I am trying to use this query to compare results because they should be the same results from both instances:
SELECT * FROM (SELECT * FROM
INSTANCE1.dbo.View1) as TEST
EXCEPT
SELECT * FROM (SELECT * FROM
[SERVER\INSTANCE2].Database.dbo.View1) as LIVE
I have tried to wrap the query in CTE, and have also been trying to specify default collation but everything I try doesn't work.
Is there a way I can query these two views on seperate instances to compare the results without creating a temp table and by getting SQL to ignore the conflict?
Thank you so much, I appreciate any help.
Well the error message tells you exactly what the problem is, but not which column or columns it belongs to, and because you use select * I have no idea what the columns names are either. You will need to identify columns in those tables that store strings, and then force then to use the same collation, something like this I think (untested):
SELECT stringcol
FROM (
SELECT stringcol collate SQL_Latin1_General_CP1_CI_AS
FROM INSTANCE1.dbo.View1) as TEST
EXCEPT
SELECT stringcol
FROM (SELECT stringcol collate SQL_Latin1_General_CP1_CI_AS
FROM [SERVER\INSTANCE2].Database.dbo.View1
) as LIVE
So you will need to specify the columns, and you will need to also specify the collation to be used for string columns.
Related
Trying to do a simple Snowflake query as such:
SELECT *
FROM TABLE
WHERE NAME_COLUMN LIKE '%ABC%'
Yet I'm getting the following error.
SQL compilation error: error line 17 at position 12 Function LIKE does not support collation: en-ci-rtrim.
What is the work around here? I don't have the ability to alter the underlying table or the collation attributes.
You can re-colate in real time:
create or replace temp table collation_demo (
uncollated_phrase varchar,
stack_phrase varchar collate 'en-ci-rtrim'
);
insert into collation_demo (uncollated_phrase, stack_phrase)
values ('pinata', 'pirata');
select *
from collation_demo
where collate(stack_phrase, 'en') like '%pi%'
order by stack_phrase
If you remove the collate() call around stack_phrase you'll get the same error. But with it, the query works as expected.
Another workaround is to use a different string comparing function that supports the existing collation. For example, contains():
select *
from collation_demo
where contains(stack_phrase, 'PI');
Works!
We've two database one is the old one which has COLLATION - SQL_Latin1_General_CP1_CI_AS and the new one with COLLATION - Latin1_General_CI_AI (probably the default one).
There's a simple Table1 (ID (int), code(nvarchar(50))) in both the databases. What I'm suppose to do is compare both the tables for its data and find the missing or extra records.
Sample data in old table has code like : 'Code1 '
Sample data in new table has code like : 'Code1 '
What I need to be able to do is compare both the data (from the 'Name' column). I'm unable to trim the data from the old table -
EXAMPLE:
SELECT LTRIM(RTRIM([Name])) from [OLDDB].dbo.Table1
returns 'Code1 ' -- NOT as expected (probably due to mis-match in charset
SELECT LTRIM(RTRIM([Name])) from [NEWDB].dbo.Table1
'Code1' -- as expected
I hope it makes sense. Besides, even if I changes the COLLATION at column level still I was not able to get the ltrim / rtrim work!
Thanks.
If the CHAR(160) is the problem, then you don't have to change collation. Just replace those CHAR(160) with proper spaces and then RTRIM will work.
SELECT LTRIM(RTRIM(REPLACE([Name], CHAR(160), ' '))) from [OLDDB].dbo.Table1
Try the below update, Hope this will fix the issue.
update [OLDDB].dbo.Table1 set Name RTRIM(replace(NAME, char(160), char(32)))
I've a thirdy-part plugin of my program that execute SQL queries (mostly are select). These queries must return a default column order and amount, such:
PACKAGEID (guid), REFDATE (datetime), MODIFYDATE (datetime), PROG (int)
Sometimes happens that some query omit one of the column specified above. In order to avoid furthers errors in the program, I would execute a sort of check just to be sure that each query executed returns the default columns.
I've already use the SQL syntax SET NOEXEC ON and SET NOEXEC OFF and might be useful also in this case. I'm currently using SQL SERVER 2008.
Any hints?
If you're able to put the result set into a temporary table, you can easily count number of columns of the table by using something like:
Select *
From tempdb.Information_Schema.COLUMNS
where TABLE_NAME like '%#temptable%'
When I do
SELECT CHAR(193)
On my local database it returns Á, but when I do the same on a database running on another server it returns ┴.
I expect Á as the correct value, how can I fix the function?
The databases were created individually, they aren't exactly the same.
Try using NChar instead of Char:
SELECT NCHAR(193)
The collation is not the same, run this to see that you get different answers
SELECT CHAR(193) collate SQL_Latin1_General_Cp1256_CI_AS
SELECT CHAR(193)
SELECT CHAR(193) Latin1_General_CI_AS
to find out the collation for the database run this
Select DATABASEPROPERTYEX(DB_name(),'Collation')
I'm still fairly new to T-SQL and SQL 2005. I need to import a column of integers from a table in database1 to a identical table (only missing the column I need) in database2. Both are sql 2005 databases. I've tried the built in import command in Server Management Studio but it's forcing me to copy the entire table. This causes errors due to constraints and 'read-only' columns (whatever 'read-only' means in sql2005). I just want to grab a single column and copy it to a table.
There must be a simple way of doing this. Something like:
INSERT INTO database1.myTable columnINeed
SELECT columnINeed from database2.myTable
Inserting won't do it since it'll attempt to insert new rows at the end of the table. What it sounds like your trying to do is add a column to the end of existing rows.
I'm not sure if the syntax is exactly right but, if I understood you then this will do what you're after.
Create the column allowing nulls in database2.
Perform an update:
UPDATE database2.dbo.tablename
SET database2.dbo.tablename.colname = database1.dbo.tablename.colname
FROM database2.dbo.tablename INNER JOIN database1.dbo.tablename ON database2.dbo.tablename.keycol = database1.dbo.tablename.keycol
There is a simple way very much like this as long as both databases are on the same server. The fully qualified name is dbname.owner.table - normally the owner is dbo and there is a shortcut for ".dbo." which is "..", so...
INSERT INTO Datbase1..MyTable
(ColumnList)
SELECT FieldsIWant
FROM Database2..MyTable
first create the column if it doesn't exist:
ALTER TABLE database2..targetTable
ADD targetColumn int null -- or whatever column definition is needed
and since you're using Sql Server 2005 you can use the new MERGE statement.
The MERGE statement has the advantage of being able to treat all situations in one statement like missing rows from source (can do inserts), missing rows from destination (can do deletes), matching rows (can do updates), and everything is done atomically in a single transaction. Example:
MERGE database2..targetTable AS t
USING (SELECT sourceColumn FROM sourceDatabase1..sourceTable) as s
ON t.PrimaryKeyCol = s.PrimaryKeyCol -- or whatever the match should be bassed on
WHEN MATCHED THEN
UPDATE SET t.targetColumn = s.sourceColumn
WHEN NOT MATCHED THEN
INSERT (targetColumn, [other columns ...]) VALUES (s.sourceColumn, [other values ..])
The MERGE statement was introduced to solve cases like yours and I recommend using it, it's much more powerful than solutions using multiple sql batch statements that basically accomplish the same thing MERGE does in one statement without the added complexity.
You could also use a cursor. Assuming you want to iterate all the records in the first table and populate the second table with new rows then something like this would be the way to go:
DECLARE #FirstField nvarchar(100)
DECLARE ACursor CURSOR FOR
SELECT FirstField FROM FirstTable
OPEN ACursor
FETCH NEXT FROM ACursor INTO #FirstField
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO SecondTable ( SecondField ) VALUES ( #FirstField )
FETCH NEXT FROM ACursor INTO #FirstField
END
CLOSE ACursor
DEALLOCATE ACursor
MERGE is only available in SQL 2008 NOT SQL 2005
insert into Test2.dbo.MyTable (MyValue) select MyValue from Test1.dbo.MyTable
This is assuming a great deal. First that the destination database is empty. Second that the other columns are nullable. You may need an update instead. To do that you will need to have a common key.