3

I have something similar to this in my Advantage database:-

drop table #test;

create table #test (x cichar(50));
insert into #test (x) values ('cheese');
insert into #test (x) values ('fromage');
insert into #test (x) values ('Queso');

select
  t1.x t1_x,
  t2.x t2_x
from
  #test t1
  inner join
  (
    select
      'CHEESE' x // String literal will be of type VARCHARFOX
    from
      system.iota
  ) t2
  on t1.x=t2.x

This gives me the message:-

poQuery: Error 7200: AQE Error: State = HY000; NativeError = 2213; [iAnywhere Solutions] [Advantage SQL Engine]Invalid comparison or operation on strings with different collations. ** Script error information: -- Location of error in the SQL statement is: 137 (line: 5 column: 1)

When I would like:-

t1_x    t2_x
cheese  CHEESE

This is because the 'CHEESE' string literal becomes type VARCHARFOX and the column in the temp table is of type cichar because I want case insensitive comparisons.

I can fix this instance by adding a "COLLATE ads_default_ci" to the comparison, however this is cumbersome and I can never remember the exact syntax of it.

I think I must be doing something fundamentally wrong with the column types or the configuration of the database, what's the elegant/right way to do this?

Pseudo Nym
  • 41
  • 4

1 Answers1

1

It's not so much the string literal which is the problem here, string literals usually behave just fine.

They get the COERCION_COMPATBILE collation:

TRY drop table #test; CATCH ALL END TRY;

create table #test (x cichar(50));
insert into #test (x) values ('cheese');
insert into #test (x) values ('fromage');
insert into #test (x) values ('Queso');

select
  t1.x t1_x,
  'CHEESE' t2_x
from
  #test t1
where
  t1.x='CHEESE'

The problem is that you are introducing a derived table and that the ADS engine determines the data type of the derived table field to be VARCHARFOX(6):

select
  'CHEESE' x
from
  system.iota

I don't think that there is an easy way to do this.

I have created an upstream request on the ADS forum.

Also I have added a feature request based on this. If it was implemented the solution would be:

select
  CICHAR'CHEESE' x
from
  system.iota

I think that this is would be a clean solution.

You should also be aware of something else:

There is a collation associated with each connection.

The NCHAR also built-in support for case-sensitive and case-insensitive collations. Which one is used depends on the collation of the current connection.

You can set the collation for the current connection using the AdsSetCollation function (or it's equivalent for you development environment, for example in ARC you can set it in the connection properties).

Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
  • Yes, you're right you do have to have a derived table for it. I was hunting for the right phrasing to describe it. But that you get something different from the derived table vs the literal is odd. – Pseudo Nym Dec 12 '14 at 13:37