Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Degun
Member

Откуда:
Сообщений: 205
Есть старое клиент-серверное приложение, с которым давно не работали, но которое необходимо запустить в работу. Есть база данных к нему в виде двух файлов: mdf и ldf.
Развернул базу данных на сервере Microsoft SQL Server 2008 R2. Для этого создал пустую базу данных, перевёл её в режим Offline. Затем заменил файлы mdf и ldf на нужные, а потом перевёл базу обратно в режим Online.
База запустилась нормально, но при запуске клиентского приложения выдаётся следующая ошибка:

implicit conversion of varchar value to varchar cannot be performed because the collation of the value is unresolved due to a collation conflict

Само приложение я менять не могу. У базы данных установил режим collation в Cyrillic_General_CI_AS, но это не помогло. Что нужно сделать чтобы клиентское приложение могло работать с базой данных?
16 янв 15, 12:24    [17126868]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
посмотрите какой у вас колейшин сервера (tempdb)
16 янв 15, 12:28    [17126898]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Degun
Member

Откуда:
Сообщений: 205
Cyrillic_General_CI_AS
16 янв 15, 12:34    [17126947]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Glory
Member

Откуда:
Сообщений: 104760
Degun
но при запуске клиентского приложения выдаётся следующая ошибка:

И как выглядит запрос, вызвавший эту ошибку ?
16 янв 15, 12:36    [17126957]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Degun
Cyrillic_General_CI_AS

пониматет в чем фишка - у вас скорее всего БД изначально созданна была в другом колейшене ,и данные в строковых\текстовых столбац имееют таки другой колейшин. Посему прямого пути нет. Просто сделайте срипт любой таблицы из студии и посмотрите кокй именно колейшин прописан в создании поля.
16 янв 15, 13:00    [17127161]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Degun
Member

Откуда:
Сообщений: 205
Maxx,

У строковых полей таблиц базы данных collation = Cyrillic_General_BIN. Поставил этот collation для всей базы, но это не помогло. Может ещё что-то нужно сделать?
16 янв 15, 13:34    [17127409]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Degun,

нц тогда поздарвляю - вы счастливчик :(
Яб скриптовал бы всю БД , менял в скрипте коллейшин на серверный и только потом переливал данные.
У вас ошибка не с клиентким приложением ,а с разницой в коллейшине вашей БД (данных) и серверный коллейшином.
16 янв 15, 13:36    [17127434]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Glory
Member

Откуда:
Сообщений: 104760
Degun
Может ещё что-то нужно сделать?

Нужно получит текст запроса, чтобы увидеть объекты, участвующие в нем
А не тыкать пальцем наугад
16 янв 15, 14:35    [17127966]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Degun
Member

Откуда:
Сообщений: 205
Glory,

Похоже ошибка происходит при вызове хранимой процедуры dbo.ap_menu2user или ap_actions_load. Текст процедур следующий:
+
ALTER procedure [dbo].[ap_menu2user]
as
begin

  create table #report (
    id numeric,
    parent_id numeric null,
    menu_type tinyint null,
    menu_order int null,
    name varchar(255) null,
    vaction_id numeric null,
    vclass_id int null,
    vuo_name varchar(30) null,
    vdw_name varchar(30) null,
    vproc_name varchar(30) null,
    vx int null,
    vy int null,
    vwidth int null,
    vheight int null,
    naction_id numeric null,
    nclass_id int null,
    nuo_name varchar(30) null,
    ndw_name varchar(30) null,
    nproc_name varchar(30) null,
    faction_id numeric null,
    fclass_id int null,
    fuo_name varchar(30) null,
    fdw_name varchar(30) null,
    fproc_name varchar(30) null,
    fx int null,
    fy int null,
    fwidth int null,
    fheight int null,
    type_id numeric null,
    menu_all_str varchar(255) null,
    is_tab tinyint null
  )
  declare @menu_id numeric(18,0)
  declare @user_id numeric(18,0)

  select @user_id=(select id from t_users where login_name=suser_sname())
  if @user_id is null goto result

  select @menu_id=(select menu_id from t_users where login_name=suser_sname())
  if @menu_id is null goto result

  insert #report (
    id,
    parent_id,
    menu_type,
    menu_order,
    name,
    naction_id,
    nclass_id,
    nuo_name,
    ndw_name,
    nproc_name,
    vaction_id,
    faction_id,
    type_id,
    menu_all_str,
    vx,
    vy,
    vwidth,
    vheight,
    is_tab
  )
  select
     t_menu.id,
     t_menu.parent_id,
     t_menu.menu_type,
     t_menu.menu_order,
     t_menu.menu_label,
     t_actions.id,
     t_actions.class_id,
     t_actions.uo_name,
     t_actions.dw_name,
     t_actions.proc_name,
     t_actions.vaction_id,
     t_actions.faction_id,
     t_actions.type_id,
     t_menu.menu_all_str,
     t_actions.x,
     t_actions.y,
     t_actions.width,
     t_actions.height,
     t_actions.is_tab
    from t_menu, t_actions, t_types, t_aladdin_products, t_action2user
   where t_menu.menu_id=@menu_id
     and t_menu.action_id = t_actions.id
     and t_actions.vaction_id is not null
     and t_actions.class_id in (1,2,3)
     and t_actions.type_id =t_types.id
     and t_types.product_id = t_aladdin_products.id
     and t_aladdin_products.is_actual = 1
     and t_action2user.suser_name=suser_sname()
     and t_actions.id=t_action2user.action_id

  update #report set
    vclass_id = t_actions.class_id,
    vuo_name = t_actions.uo_name,
    vdw_name = t_actions.dw_name,
    vproc_name = t_actions.proc_name
    from t_actions
   where t_actions.id = #report.vaction_id

  insert #report (
    id,
    parent_id,
    menu_type,
    menu_order,
    name,
    vaction_id,
    vclass_id,
    vuo_name,
    vdw_name,
    vproc_name,
    vx,
    vy,
    vwidth,
    vheight,
    faction_id,
    type_id,
    menu_all_str,
    is_tab
  )
  select
     t_menu.id,
     t_menu.parent_id,
     t_menu.menu_type,
     t_menu.menu_order,
     t_menu.menu_label,
     t_actions.id,
     t_actions.class_id,
     t_actions.uo_name,
     t_actions.dw_name,
     t_actions.proc_name,
     t_actions.x,
     t_actions.y,
     t_actions.width,
     t_actions.height,
     t_actions.faction_id,
     t_actions.type_id,
     t_menu.menu_all_str,
     t_actions.is_tab
    from t_menu, t_action2user, t_actions, t_types, t_aladdin_products
   where t_menu.menu_id=@menu_id
     and t_actions.id=t_menu.action_id
     and t_actions.class_id in (4,5)
     and t_actions.type_id=t_types.id
     and t_types.product_id=t_aladdin_products.id
     and t_aladdin_products.is_actual = 1
     and t_action2user.suser_name=suser_sname()
     and t_actions.id=t_action2user.action_id

  update #report set
    fclass_id = t_actions.class_id,
    fuo_name = t_actions.uo_name,
    fdw_name = t_actions.dw_name,
    fproc_name = t_actions.proc_name,
    fx = t_actions.x,
    fy = t_actions.y,
    fwidth = t_actions.width,
    fheight = t_actions.height
    from t_actions
   where t_actions.id = #report.faction_id
/*
  insert into #report
      (id,
       parent_id,
       menu_type,
       name,
       menu_order)
  select distinct
       t_menu.id,
       t_menu.parent_id,
       t_menu.menu_type,
       t_menu.menu_label,
       t_menu.menu_order
   from t_menu, #report
  where t_menu.menu_type = 1
--  and  #report.menu_all_str like t_menu.menu_all_str + '%'
*/
  declare @cnt int
  select @cnt=(select count(*) from #report)

  insert into #report
      (id,
       parent_id,
       menu_type,
       name,
       menu_order)
  select distinct
       t_menu.id,
       t_menu.parent_id,
       t_menu.menu_type,
       t_menu.menu_label,
       t_menu.menu_order
   from t_menu, #report
  where t_menu.menu_type = 1
    and t_menu.id=#report.parent_id
    and t_menu.id not in (select id from #report)

  while @cnt<(select count(*) from #report) begin
     select @cnt=(select count(*) from #report)

     insert into #report
         (id,
          parent_id,
          menu_type,
          name,
          menu_order)
     select distinct
          t_menu.id,
          t_menu.parent_id,
          t_menu.menu_type,
          t_menu.menu_label,
          t_menu.menu_order
     from t_menu, #report
    where t_menu.menu_type = 1
      and t_menu.id=#report.parent_id
      and t_menu.id not in (select id from #report)
  end


result:

select
    sid = convert(varchar, #report.id),
    parent_sid = convert(varchar, #report.parent_id),
    #report.menu_type,
    #report.name,
    vaction_sid = convert(varchar, #report.vaction_id),
    #report.vclass_id,
    #report.vuo_name,
    #report.vdw_name,
    #report.vproc_name,
    #report.vx,
    #report.vy,
    #report.vwidth,
    #report.vheight,
    naction_sid = convert(varchar, #report.naction_id),
    #report.nclass_id,
    #report.nuo_name,
    #report.ndw_name,
    #report.nproc_name,
    faction_sid = convert(varchar, #report.faction_id),
    #report.fclass_id,
    #report.fuo_name,
    #report.fdw_name,
    #report.fproc_name,
    #report.fx,
    #report.fy,
    #report.fwidth,
    #report.fheight,
    type_sid = convert(varchar, #report.type_id),
    #report.is_tab
  from #report
  order by #report.menu_order, #report.name

  drop table #report
end

ALTER procedure [dbo].[ap_actions_load]
as
begin

create table #report (
    name varchar(255) null,
    vaction_id numeric null,
    vaction_code varchar(60) null,
    vclass_id int null,
    vuo_name varchar(30) null,
    vdw_name varchar(30) null,
    vproc_name varchar(30) null,
    vx int null,
    vy int null,
    vwidth int null,
    vheight int null,
    naction_id numeric null,
    nclass_id int null,
    nuo_name varchar(30) null,
    ndw_name varchar(30) null,
    nproc_name varchar(30) null,
    type_id numeric null,
    state_id numeric null,
    is_tab tinyint null
)
--
-- Невизуальные методы
--
insert #report (
    name,
    naction_id,
    nclass_id,
    nuo_name,
    ndw_name,
    nproc_name,
    vaction_id,
    type_id,
    state_id,
    is_tab,
    vx,
    vy,
    vwidth,
    vheight
)
select
    t_actions.action_name,
    t_actions.id,
    t_actions.class_id,
    t_actions.uo_name,
    t_actions.dw_name,
    t_actions.proc_name,
    t_actions.vaction_id,
    t_actions.type_id,
    t_state2action2user.state_id,
    t_actions.is_tab,
    t_actions.x,
    t_actions.y,
    t_actions.width,
    t_actions.height
 from t_actions, t_state2action2user
where t_actions.isvisible=0
  and t_actions.class_id in (1,2,3,9)
  and t_state2action2user.action_id=t_actions.id
  and t_state2action2user.suser_name=suser_sname()
--
-- Визуальные к невизуальным
--
update #report
   set vaction_code = t_actions.action_code,
       vclass_id = t_actions.class_id,
       vuo_name = t_actions.uo_name,
       vdw_name = t_actions.dw_name,
       vproc_name = t_actions.proc_name
  from t_actions
where t_actions.id = #report.vaction_id
--
-- Просмотры
--
insert #report (
    name,
    vaction_id,
    vaction_code,
    vclass_id,
    vuo_name,
    vdw_name,
    vproc_name,
    vx,
    vy,
    vwidth,
    vheight,
    type_id,
    state_id,
    is_tab
  )
select
    t_actions.action_name,
    t_actions.id,
    t_actions.action_code,
    t_actions.class_id,
    t_actions.uo_name,
    t_actions.dw_name,
    t_actions.proc_name,
    t_actions.x,
    t_actions.y,
    t_actions.width,
    t_actions.height,
    t_actions.type_id,
    t_state2action2user.state_id,
    t_actions.is_tab
   from t_actions, t_state2action2user
  where t_actions.isvisible=0
    and t_actions.class_id=5
    and t_state2action2user.action_id=t_actions.id
    and t_state2action2user.suser_name=suser_sname()

update #report
   set name = name + ' ' +(select type_name from t_types
                            where t_types.id=#report.type_id
                              and #report.nclass_id=1)

select
    #report.name,
    vaction_sid = convert(varchar, #report.vaction_id),
    #report.vaction_code,
    #report.vclass_id,
    #report.vuo_name,
    #report.vdw_name,
    #report.vproc_name,
    #report.vx,
    #report.vy,
    #report.vwidth,
    #report.vheight,
    naction_sid = convert(varchar, #report.naction_id),
    #report.nclass_id,
    #report.nuo_name,
    #report.ndw_name,
    #report.nproc_name,
    convert(varchar, #report.type_id) as type_sid,
    convert(varchar, #report.state_id) as state_sid,
    #report.is_tab
  from #report
 order by nclass_id, vclass_id , #report.name
--
-- Связи
--
select
  convert(varchar, t_relation.s_type_id) as s_type_sid,
  convert(varchar, t_relation.t_type_id) as t_type_sid
from t_relation
where t_relation.class_id in (5)
order by t_relation.s_type_id,t_relation.rel_order
--
-- Вхождение в меню
--
select
    t_actions.action_name,
    convert(varchar, t_actions.id) as vaction_sid,
    t_actions.action_code as vaction_code,
    t_actions.class_id as class_id,
    t_actions.uo_name as vuo_name,
    t_actions.dw_name as vdw_name,
    t_actions.proc_name as vproc_name,
    t_actions.x as vx,
    t_actions.y as vy,
    t_actions.width vwidth,
    t_actions.height as vheight,
    convert(varchar, t_actions.type_id) as type_sid,
    convert(varchar, t_state2action2user.state_id) as state_sid,
    t_actions.is_tab,
    t_relation.s_type_id as rel_type_id
   from t_relation, t_state2action2user, t_actions
  where t_relation.class_id = 6
    and t_relation.action_id = t_actions.id
    and t_actions.class_id in (4, 5)
    and t_relation.action_id = t_state2action2user.action_id
    and t_state2action2user.suser_name=suser_sname()
    and exists(select 1 from t_types, t_aladdin_products
                where t_types.id=t_relation.t_type_id
                  and t_aladdin_products.id=t_types.product_id
                  and t_aladdin_products.is_actual=1)
drop table #report
end

Модератор: Не надо всем разрывать монитор. Убирайте ваши простыни кода в тег spoiler


Сообщение было отредактировано: 16 янв 15, 14:56
16 янв 15, 14:52    [17128129]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Degun
Member

Откуда:
Сообщений: 205
Скорее всего ошибка в процедуре ap_actions_load, т. к. после её вызова клиентское приложение было завершено с ошибкой.
16 янв 15, 14:54    [17128145]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Glory
Member

Откуда:
Сообщений: 104760
Degun
Текст процедур следующий:

Еще раз
Нужен запрос, который вызывает ошибку
16 янв 15, 14:56    [17128170]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
да до одного места ...
ваша табла #report создаеться в tempdb у который серверный коллейшин...
а вот ето все t_menu, t_actions, t_types, t_aladdin_products, t_action2user (данные ) в старом коллейшине
Усе . вот такая сказочка
16 янв 15, 14:56    [17128174]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
o-o
Guest
лучше всего иметь сервер с нужным коллэйшеном (тем, что у базы. т.е. Cyrillic_General_BIN).
у вас варианты: или руками теперь для всех темповых объектов коллэйшен прописывать,
или развернуть эту базу на сервере с тем же коллэйшеном, что и база.
т.е. на другом вообще сервере. рядом его поставить или,
если на вашем сервере больше баз нету, ему коллэйшен сменить
16 янв 15, 15:02    [17128233]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8316
Бинари- это вообще сурово, непонятно что сортировка выдаст - сначала большие, потом маленькие...
16 янв 15, 15:23    [17128411]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Glory
Member

Откуда:
Сообщений: 104760
Maxx
Усе . вот такая сказочка

Это не все
Еще нужно в запросе _сравнить_ поля с разными коллейтами
16 янв 15, 15:30    [17128481]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Glory
Это не все
Еще нужно в запросе _сравнить_ поля с разными коллейтами

как на меня - проще заксриптовать БД с данными ,поменять колейшин и пересозать БД.
Чтоб все было в серверном коллейшене.
Ето займет гораздо меньше времени ,как на меня, чем искать все места где надо сделать описаное вами.
16 янв 15, 15:36    [17128521]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
iap
Member

Откуда: Москва
Сообщений: 47047
Владислав Колосов
Бинари- это вообще сурово, непонятно что сортировка выдаст - сначала большие, потом маленькие...
Я всю жизнь с этим COLLATE живу - замечательно!
Главное теперь не менять!
16 янв 15, 15:49    [17128638]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
iap
Member

Откуда: Москва
Сообщений: 47047
Maxx
Glory
Это не все
Еще нужно в запросе _сравнить_ поля с разными коллейтами

как на меня - проще заксриптовать БД с данными ,поменять колейшин и пересозать БД.
Чтоб все было в серверном коллейшене.
Ето займет гораздо меньше времени ,как на меня, чем искать все места где надо сделать описаное вами.
Но надо сказать, что свойства этих COLLATEов настолько разные,
что наверно что-то где-то ещё навернётся после таких манипуляций.
В одном месте отработает, а вдругом не просто отработает, а с большими сюрпризами.
16 янв 15, 15:51    [17128671]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка связанная с collation при работе с базой данных из клиентского приложения  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
iap,

а кто говорил что будет просто ?
Все равно универсального решения,увы,нет для такого случая.
Я предложил самый просто путь как на меня, не более того
Glory предложил свой

У обоих варианто куча + и -

Выберать ТС , все равно кроме него никто его БД не видел
16 янв 15, 15:57    [17128725]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить