Сведения о вопросе

Kimsanov

18:03, 8th August, 2020

Теги

sql-server    

Несогласованность между MS Sql 2k и 2k5 со столбцами в качестве аргументов функции

Просмотров: 354   Ответов: 2

У меня возникли проблемы с получением следующего для работы в SQL Server 2k, но он работает в 2k5:

--works in 2k5, not in 2k

create view foo as    
SELECT  usertable.legacyCSVVarcharCol as testvar     
FROM  usertable   
WHERE rsrcID in
    (  select val     
       from
       dbo.fnSplitStringToInt(usertable.legacyCSVVarcharCol, default)
    )

--error message:    
Msg 170, Level 15, State 1, Procedure foo, Line 4    
Line 25: Incorrect syntax near '.'.

Итак, legacyCSVVarcharCol-это столбец, содержащий разделенные запятыми списки INTs. Я понимаю, что это огромный WTF, но это устаревший код,и сейчас ничего нельзя сделать со схемой. Передача "testvar" в качестве аргумента функции также не работает в 2k. На самом деле, это приводит к немного другой (и даже более странной ошибке):

Msg 155, Level 15, State 1, Line 8

'testvar' is not a recognized OPTIMIZER LOCK HINTS option.

Передача жестко закодированной строки в качестве аргумента fnSplitStringToInt работает как в 2k, так и в 2k5.

Кто-нибудь знает, почему это не работает в 2k? Возможно, это известная ошибка в планировщике запросов? Любые предложения о том, как заставить его работать? Опять же, я понимаю, что реальный ответ: "Не храните списки CSV в вашем DB!- но, увы, это не в моей власти.

Некоторые примеры данных, если это помогает:

INSERT INTO usertable (legacyCSVVarcharCol) values ('1,2,3');
INSERT INTO usertable (legacyCSVVarcharCol) values ('11,13,42');

Обратите внимание, что данные в таблице не имеют значения, поскольку это синтаксическая ошибка, и она возникает, даже если usertable полностью пуста.

EDIT: понимая, что, возможно, первоначальный пример был неясным, вот два примера, один из которых работает, а другой - нет, что должно подчеркнуть проблему, которая возникает:

--fails in sql2000, works in 2005

SELECT t1.* 
FROM usertable t1
WHERE 1 in 
    (Select val 
     from 
     fnSplitStringToInt(t1.legacyCSVVarcharCol, ',')
    )

--works everywhere:

SELECT t1.*   
FROM usertable t1
WHERE 1 in 
    ( Select val 
      from 
      fnSplitStringToInt('1,4,543,56578', ',')
    )

Обратите внимание, что единственное различие заключается в том, что первый аргумент для fnSplitStringToInt-это столбец в случае, который завершается неудачей в 2k, и литеральная строка в случае, который завершается успешно в обоих случаях.



  Сведения об ответе

fo_I_K

22:55, 15th August, 2020

Передача значений столбцов в табличную пользовательскую функцию не поддерживается в SQL Server 2000, Вы можете использовать только константы, поэтому следующая (более простая версия) также не будет выполнена:

SELECT *, (SELECT TOP 1 val FROM dbo.fnSplitStringToInt(usertable.legacyCSVVarcharCol, ','))
FROM usertable

Он будет работать на SQL Server 2005, хотя, как вы узнали.


  Сведения об ответе

lourence

11:48, 24th August, 2020

Я не думаю, что функции могут иметь значения по умолчанию в функциях в SS2K.

Что происходит, когда вы запускаете этот SQL в SS2K?

select val     
from dbo.fnSplitStringToInt('1,2,3', default)


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться